gem-patch 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/lib/rubygems/commands/patch_command.rb +25 -10
- data/lib/rubygems/package-1.8.rb +4 -3
- data/lib/rubygems/patcher.rb +69 -12
- data/lib/rubygems_plugin.rb +1 -1
- data/test/rubygems/test_gem_commands_patch_command.rb +3 -3
- data/test/rubygems/test_gem_patch.rb +21 -2
- metadata +10 -10
- data/rakefile.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cccc1bd307891a4592e49f1206ab4beb21a221f4
|
4
|
+
data.tar.gz: ff5d1571ac0eeafea18baf915c22f3ab0f0e44a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 684b0b96590e470851c0923b9f4e63add226b0de7767089b80630834d00f0cb606fea1ac5bc23a48c8363023535ef6b73767c47a86730df0efc56a6aef81dc81
|
7
|
+
data.tar.gz: a829e64b45b42710e63eed28b16407ea353b6962ec508664bc6bb3da66f6275a9f726f257f87a8c6dbd30f05d9af54f1410492b597421cdf929673619534d3f5
|
data/README.md
CHANGED
@@ -27,11 +27,16 @@ On Fedora you can use YUM:
|
|
27
27
|
| -pNUMBER | --strip-numberNUMBER | Sets the file name strip count to NUMBER. |
|
28
28
|
| -FNUMBER | --fuzz=NUMBER | Set NUMBER of lines to ignore in looking for places to install a hunk. |
|
29
29
|
| -oFILE | --output=FILE | Set output FILE. |
|
30
|
+
| --patch-options=OPTIONS || Pass additional patch command options. |
|
31
|
+
| -cPATHS | --copy-in=PATHS | Copy in files or folders (separated by comma) |
|
32
|
+
| -rPATHS | --remove=PATHS | Remove files or folders before rebuild (separated by comma) |
|
30
33
|
| --dry-run | | Print the results from patching, but do not change any files. |
|
31
34
|
| --verbose | | Print additional info and STDOUT from `patch` command. |
|
32
35
|
|
33
36
|
For versions higher than 0.1.4 `--dry-run` switch behaviour has been changed and it's not the same as in original `patch` command. Instead, `gem-patch` lets `patch` command modify files, but doesn't override the gem to be patched nor the output file at the end. This way we can easily use dry run also for patches involving more diffs changing each other.
|
34
37
|
|
38
|
+
If you need to check patching files that are not part of .gem release (such as a separate test suite), you can do it with `--copy-in=test,folders` option. If you don't want to include those additional files then delete them with `--remove=test,folders`.
|
39
|
+
|
35
40
|
## Requirements
|
36
41
|
|
37
42
|
This version is build for both RubyGems 1.8 and RubyGems 2.0.
|
@@ -1,28 +1,43 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'rubygems/command'
|
2
|
+
require 'rubygems/patcher'
|
3
3
|
|
4
4
|
class Gem::Commands::PatchCommand < Gem::Command
|
5
5
|
def initialize
|
6
|
-
super
|
6
|
+
super 'patch', 'Patch the gem with the given patches and generate the patched gem',
|
7
7
|
:output => Dir.pwd, :strip => 0
|
8
8
|
|
9
9
|
# Same as 'patch -pNUMBER' on Linux machines
|
10
|
-
add_option('-pNUMBER', '--strip=NUMBER', 'Set the file name strip count to NUMBER
|
10
|
+
add_option('-pNUMBER', '--strip=NUMBER', 'Set the file name strip count to NUMBER') do |number, options|
|
11
11
|
options[:strip] = number
|
12
12
|
end
|
13
13
|
|
14
14
|
# Number of lines to ignore in looking for places to install a hunk
|
15
|
-
add_option('-FNUMBER', '--fuzz=NUMBER', 'Set NUMBER of lines to ignore in looking for places to install a hunk
|
15
|
+
add_option('-FNUMBER', '--fuzz=NUMBER', 'Set NUMBER of lines to ignore in looking for places to install a hunk') do |number, options|
|
16
16
|
options[:fuzz] = number
|
17
17
|
end
|
18
|
+
|
19
|
+
# Pass other options that are not directly implemented
|
20
|
+
add_option('--patch-options=OPTIONS', 'Pass additional OPTIONS to the patch command') do |opts, options|
|
21
|
+
options[:patch_options] = opts
|
22
|
+
end
|
23
|
+
|
24
|
+
# Copy additional files or dirs to the unpacked .gem file before patching
|
25
|
+
add_option('-cPATHS', '--copy-in=PATHS', 'Copy in additional files or dirs before patching separated by comma') do |paths, options|
|
26
|
+
options[:copy_in] = paths
|
27
|
+
end
|
28
|
+
|
29
|
+
# Remove files or dirs before rebuilt
|
30
|
+
add_option('-rPATHS', '--remove=PATHS', 'Remove files or dirs before repacking the patched gem') do |paths, options|
|
31
|
+
options[:remove] = paths
|
32
|
+
end
|
18
33
|
|
19
34
|
# Set output file to FILE instead of overwritting
|
20
|
-
add_option('-oFILE', '--output=FILE', 'Set output FILE
|
35
|
+
add_option('-oFILE', '--output=FILE', 'Set output FILE') do |file, options|
|
21
36
|
options[:outfile] = file
|
22
37
|
end
|
23
38
|
|
24
39
|
# Dry run only shows expected output from the patching process
|
25
|
-
add_option('--dry-run', 'Print the results from patching, but do not change any files
|
40
|
+
add_option('--dry-run', 'Print the results from patching, but do not change any files') do |file, options|
|
26
41
|
options[:dry_run] = true
|
27
42
|
end
|
28
43
|
end
|
@@ -37,7 +52,7 @@ class Gem::Commands::PatchCommand < Gem::Command
|
|
37
52
|
|
38
53
|
def description # :nodoc:
|
39
54
|
desc = <<-EOF
|
40
|
-
|
55
|
+
gem-patch is a RubyGems plugin that helps to patch gems without manually opening and rebuilding them.
|
41
56
|
It opens a given .gem file, extracts it, patches it with system `patch` command,
|
42
57
|
clones its spec, updates the file list and builds the patched gem.
|
43
58
|
EOF
|
@@ -55,13 +70,13 @@ class Gem::Commands::PatchCommand < Gem::Command
|
|
55
70
|
# No gem
|
56
71
|
unless gemfile
|
57
72
|
raise Gem::CommandLineError,
|
58
|
-
|
73
|
+
'Please specify a gem file on the command line (e.g. gem patch foo-0.1.0.gem PATCH [PATCH ...])'
|
59
74
|
end
|
60
75
|
|
61
76
|
# No patches
|
62
77
|
if patches.empty?
|
63
78
|
raise Gem::CommandLineError,
|
64
|
-
|
79
|
+
'Please specify patches to apply (e.g. gem patch foo-0.1.0.gem foo.patch bar.patch ...)'
|
65
80
|
end
|
66
81
|
|
67
82
|
patcher = Gem::Patcher.new(gemfile, options[:output])
|
data/lib/rubygems/package-1.8.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'rubygems/installer'
|
2
|
+
require 'rubygems/builder'
|
3
3
|
|
4
4
|
##
|
5
|
-
# Simulate RubyGems 2.0 behavior to use master branch
|
5
|
+
# Simulate RubyGems 2.0 behavior to use master branch
|
6
|
+
# of gem-patch plugin with RubyGems 1.8
|
6
7
|
|
7
8
|
module Gem::Package
|
8
9
|
def self.new gem
|
data/lib/rubygems/patcher.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'rubygems/package'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Gem::Patcher is used to patch .gem files
|
7
|
+
# by calling system patch command
|
4
8
|
|
5
9
|
class Gem::Patcher
|
6
10
|
include Gem::UserInteraction
|
7
11
|
|
8
12
|
if Gem::VERSION < '2.0'
|
9
|
-
require
|
13
|
+
require 'rubygems/package-1.8'
|
10
14
|
end
|
11
15
|
|
12
16
|
class PatchCommandMissing < StandardError; end
|
@@ -22,21 +26,24 @@ class Gem::Patcher
|
|
22
26
|
end
|
23
27
|
|
24
28
|
##
|
25
|
-
# Patch the gem, move the new patched gem
|
29
|
+
# Patch the gem, move the new patched gem
|
30
|
+
# to +options[:outfile]+ and return the path
|
26
31
|
|
27
32
|
def patch_with(patches, options)
|
28
|
-
@output = []
|
33
|
+
@std, @output = [], []
|
29
34
|
|
30
35
|
check_patch_command_is_installed
|
31
36
|
extract_gem
|
37
|
+
copy_in(options[:copy_in], @target_dir) if options[:copy_in]
|
32
38
|
|
33
39
|
# Apply all patches
|
34
40
|
patches.each do |patch|
|
35
41
|
info 'Applying patch ' + patch
|
36
|
-
apply_patch(patch, options)
|
42
|
+
@std << apply_patch(patch, options)
|
37
43
|
end
|
38
|
-
|
39
|
-
|
44
|
+
remove(options[:remove], @target_dir) if options[:remove]
|
45
|
+
# Rebuild only if there weren't any problems
|
46
|
+
build_patched_gem unless failed?
|
40
47
|
|
41
48
|
options[:outfile] ||= File.join(@output_dir, @package.spec.file_name)
|
42
49
|
FileUtils.mv((File.join @target_dir, @package.spec.file_name), options[:outfile]) unless options[:dry_run]
|
@@ -45,16 +52,25 @@ class Gem::Patcher
|
|
45
52
|
options[:outfile]
|
46
53
|
end
|
47
54
|
|
55
|
+
##
|
56
|
+
# Apply one +patch+ at a time using +options+
|
57
|
+
#
|
58
|
+
# Default options:
|
59
|
+
# options[:strip] = 1
|
60
|
+
# options[:fuzz] = 2
|
61
|
+
|
48
62
|
def apply_patch(patch, options)
|
49
63
|
options[:strip] ||= 1
|
50
64
|
options[:fuzz] ||= 2
|
51
65
|
|
52
66
|
patch_path = File.expand_path(patch)
|
53
67
|
info 'Path to the patch to apply: ' + patch_path
|
68
|
+
copy_in(options[:copy_in], @target_dir) if options[:copy_in]
|
54
69
|
|
55
70
|
# Apply the patch by calling 'patch -pNUMBER < patch'
|
56
71
|
Dir.chdir @target_dir do
|
57
|
-
|
72
|
+
opts = ["--verbose", "-p#{options[:strip]}", "--fuzz=#{options[:fuzz]}", "#{options[:patch_options]}"]
|
73
|
+
IO.popen("patch #{opts.join(' ')} < #{patch_path} 2>&1") do |out|
|
58
74
|
std = out.readlines
|
59
75
|
out.close
|
60
76
|
info std
|
@@ -66,25 +82,47 @@ class Gem::Patcher
|
|
66
82
|
@output << "Error: Unable to patch with #{patch}."
|
67
83
|
|
68
84
|
unless Gem.configuration.really_verbose
|
69
|
-
@output <<
|
85
|
+
@output << 'Run gem patch with --verbose option to swich to verbose mode.'
|
70
86
|
end
|
71
87
|
end
|
72
88
|
end
|
89
|
+
std
|
73
90
|
end
|
74
91
|
end
|
75
92
|
end
|
76
93
|
|
94
|
+
##
|
95
|
+
# Print results from patching if
|
96
|
+
# Gem.configuration.really_verbose
|
97
|
+
|
77
98
|
def print_results
|
78
99
|
@output.each do |msg|
|
79
100
|
say msg
|
80
101
|
end
|
81
102
|
end
|
82
103
|
|
104
|
+
##
|
83
105
|
# Return output lines
|
106
|
+
|
84
107
|
def output
|
85
108
|
@output
|
86
109
|
end
|
87
110
|
|
111
|
+
##
|
112
|
+
# Return standard output
|
113
|
+
# from patch command
|
114
|
+
|
115
|
+
def std
|
116
|
+
@std
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Return false if any of the pathes failed
|
121
|
+
|
122
|
+
def failed?
|
123
|
+
@std.join(' ') =~ /.*Hunk #[0-9]+ (ignored|failed).*/
|
124
|
+
end
|
125
|
+
|
88
126
|
private
|
89
127
|
|
90
128
|
def extract_gem
|
@@ -106,6 +144,24 @@ class Gem::Patcher
|
|
106
144
|
end
|
107
145
|
end
|
108
146
|
|
147
|
+
def copy_in(paths, target)
|
148
|
+
origins = paths.split(',')
|
149
|
+
origins.each do |p|
|
150
|
+
if Dir.exists?(p) || File.exists?(p)
|
151
|
+
FileUtils.cp_r(p, File.join(target, File.basename(p)))
|
152
|
+
else
|
153
|
+
FileUtils.cp_r(File.join(Dir.pwd, p), File.join(target, p))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def remove(paths, target)
|
159
|
+
removals = paths.split(',')
|
160
|
+
removals.each do |r|
|
161
|
+
FileUtils.rm_r File.join(target, r)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
109
165
|
def info(msg)
|
110
166
|
say msg if Gem.configuration.really_verbose
|
111
167
|
end
|
@@ -148,7 +204,8 @@ class Gem::Patcher
|
|
148
204
|
begin
|
149
205
|
IO.popen('patch --version')
|
150
206
|
rescue Exception
|
151
|
-
raise PatchCommandMissing,
|
207
|
+
raise PatchCommandMissing, \
|
208
|
+
'Calling `patch` command failed. Do you have it installed?'
|
152
209
|
end
|
153
210
|
end
|
154
211
|
end
|
data/lib/rubygems_plugin.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require
|
1
|
+
require 'rubygems/command_manager'
|
2
2
|
Gem::CommandManager.instance.register_command :patch
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'rubygems/test_case'
|
2
|
+
require 'rubygems/commands/patch_command'
|
3
3
|
|
4
4
|
class TestGemCommandsPatchCommand < Gem::TestCase
|
5
5
|
def setup
|
@@ -31,4 +31,4 @@ class TestGemCommandsPatchCommand < Gem::TestCase
|
|
31
31
|
|
32
32
|
assert_match 'Please specify patches to apply (e.g. gem patch foo-0.1.0.gem foo.patch bar.patch ...)', e.message
|
33
33
|
end
|
34
|
-
end
|
34
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'rubygems/test_case'
|
2
|
+
require 'rubygems/patcher'
|
3
3
|
|
4
4
|
class TestGemPatch < Gem::TestCase
|
5
5
|
def setup
|
@@ -81,6 +81,25 @@ class TestGemPatch < Gem::TestCase
|
|
81
81
|
assert_equal patched_file, file_contents('foo.rb')
|
82
82
|
end
|
83
83
|
|
84
|
+
##
|
85
|
+
# Test passing additional options
|
86
|
+
|
87
|
+
def test_use_outfile_for_output
|
88
|
+
@options[:patch_options] = '--help'
|
89
|
+
|
90
|
+
gemfile = bake_testing_gem
|
91
|
+
|
92
|
+
patches = []
|
93
|
+
patches << bake_change_file_patch
|
94
|
+
|
95
|
+
# Creates new patched gem in @gems_dir
|
96
|
+
patcher = Gem::Patcher.new(gemfile, @gems_dir)
|
97
|
+
patched_gem = patcher.patch_with(patches, @options)
|
98
|
+
|
99
|
+
assert_equal 0, /.*Usage: patch \[OPTION\].*/ =~ patcher.std.join(' ')
|
100
|
+
end
|
101
|
+
|
102
|
+
|
84
103
|
##
|
85
104
|
# Test changing a file in a gem with -F0 option
|
86
105
|
|
metadata
CHANGED
@@ -1,27 +1,26 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem-patch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josef Stribny
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
|
-
|
15
|
-
It opens a given .gem file, extracts it, patches it with system
|
14
|
+
gem-patch is a RubyGems plugin that helps to patch gems without manually opening and rebuilding them.
|
15
|
+
It opens a given .gem file, extracts it, patches it with system patch command,
|
16
16
|
clones its spec, updates the file list and builds the patched gem.
|
17
|
-
email:
|
17
|
+
email: strzibny@strzibny.name
|
18
18
|
executables: []
|
19
19
|
extensions: []
|
20
20
|
extra_rdoc_files: []
|
21
21
|
files:
|
22
|
-
- README.md
|
23
22
|
- LICENCE
|
24
|
-
-
|
23
|
+
- README.md
|
25
24
|
- lib/rubygems/commands/patch_command.rb
|
26
25
|
- lib/rubygems/package-1.8.rb
|
27
26
|
- lib/rubygems/patcher.rb
|
@@ -38,18 +37,19 @@ require_paths:
|
|
38
37
|
- lib
|
39
38
|
required_ruby_version: !ruby/object:Gem::Requirement
|
40
39
|
requirements:
|
41
|
-
- -
|
40
|
+
- - ">="
|
42
41
|
- !ruby/object:Gem::Version
|
43
42
|
version: 1.8.7
|
44
43
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
44
|
requirements:
|
46
|
-
- -
|
45
|
+
- - ">="
|
47
46
|
- !ruby/object:Gem::Version
|
48
47
|
version: 1.8.0
|
49
48
|
requirements: []
|
50
49
|
rubyforge_project:
|
51
|
-
rubygems_version: 2.
|
50
|
+
rubygems_version: 2.2.2
|
52
51
|
signing_key:
|
53
52
|
specification_version: 4
|
54
53
|
summary: RubyGems plugin for patching gems.
|
55
54
|
test_files: []
|
55
|
+
has_rdoc:
|
data/rakefile.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'rubygems/package_task'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rdoc/task'
|
4
|
-
|
5
|
-
gemspec = Gem::Specification.new do |s|
|
6
|
-
s.name = "gem-patch"
|
7
|
-
s.version = "0.1.5"
|
8
|
-
s.platform = Gem::Platform::RUBY
|
9
|
-
s.summary = "RubyGems plugin for patching gems."
|
10
|
-
s.description = <<-EOF
|
11
|
-
`gem-patch` is a RubyGems plugin that helps to patch gems without manually opening and rebuilding them.
|
12
|
-
It opens a given .gem file, extracts it, patches it with system `patch` command,
|
13
|
-
clones its spec, updates the file list and builds the patched gem.
|
14
|
-
EOF
|
15
|
-
s.homepage = "http://github.com/strzibny/gem-patch"
|
16
|
-
s.licenses = ["MIT"]
|
17
|
-
s.author = "Josef Stribny"
|
18
|
-
s.email = "jstribny@redhat.com"
|
19
|
-
s.required_ruby_version = ">= 1.8.7"
|
20
|
-
s.required_rubygems_version = ">= 1.8.0"
|
21
|
-
s.files = FileList["README.md", "LICENCE", "rakefile.rb",
|
22
|
-
"lib/**/*.rb", "test/**/test*.rb"]
|
23
|
-
end
|
24
|
-
|
25
|
-
Gem::PackageTask.new gemspec do |pkg|
|
26
|
-
end
|
27
|
-
|
28
|
-
Rake::RDocTask.new do |rd|
|
29
|
-
rd.main = "README.md"
|
30
|
-
rd.rdoc_files.include("README.md", "lib/**/*.rb")
|
31
|
-
end
|
32
|
-
|
33
|
-
Rake::TestTask.new('test') do |t|
|
34
|
-
t.libs << 'test'
|
35
|
-
t.pattern = 'test/**/test*.rb'
|
36
|
-
t.verbose = true
|
37
|
-
end
|
38
|
-
|
39
|
-
task :default => [:test]
|