svn-transform 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/examples/fixtures/original.rb +2 -0
- data/examples/fixtures/result.rb +2 -0
- data/examples/svn-transform/transform/newline_example.rb +8 -0
- data/lib/svn-transform.rb +80 -18
- data/lib/svn-transform/transform/newline.rb +2 -0
- data/svn-transform.gemspec +86 -0
- metadata +4 -3
data/Rakefile
CHANGED
@@ -16,7 +16,7 @@ EOF
|
|
16
16
|
gem.email = "jmorgan@morgancreative.net"
|
17
17
|
gem.homepage = "http://github.com/jm81/svn-props-to-yaml"
|
18
18
|
gem.authors = ["Jared Morgan"]
|
19
|
-
gem.add_dependency('svn-fixture', '= 0.
|
19
|
+
gem.add_dependency('svn-fixture', '= 0.3.0')
|
20
20
|
gem.add_development_dependency "spicycode-micronaut"
|
21
21
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
22
22
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -47,6 +47,7 @@ SvnFixture.repo('original') do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
file 'computers.txt' do
|
50
|
+
prop 'todelete', 'delete this'
|
50
51
|
body "---\r\neol: CRLF\r\n\---\r\n\r\ncomputers do not \r\nlike salsa so much."
|
51
52
|
end
|
52
53
|
end
|
@@ -62,6 +63,7 @@ SvnFixture.repo('original') do
|
|
62
63
|
dir 'articles' do
|
63
64
|
file 'computers.txt' do
|
64
65
|
prop 'alt:title', 'Computers'
|
66
|
+
propdel 'todelete'
|
65
67
|
end
|
66
68
|
end
|
67
69
|
end
|
data/examples/fixtures/result.rb
CHANGED
@@ -63,6 +63,7 @@ SvnFixture.repo('result') do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
file 'computers.md' do
|
66
|
+
prop 'todelete', 'delete this'
|
66
67
|
body "--- \ntitle: Computers\neol: CRLF\npublished_at: 2009-07-01 12:00:00\n---\n\ncomputers do not \nlike salsa so much."
|
67
68
|
end
|
68
69
|
end
|
@@ -80,6 +81,7 @@ SvnFixture.repo('result') do
|
|
80
81
|
dir 'articles' do
|
81
82
|
file 'computers.md' do
|
82
83
|
prop 'alt:title', 'Computers'
|
84
|
+
propdel 'todelete'
|
83
85
|
body "--- \ntitle: Computers\neol: CRLF\npublished_at: 2009-07-01 12:00:00\n---\n\ncomputers do not \nlike salsa so much."
|
84
86
|
end
|
85
87
|
end
|
@@ -41,6 +41,14 @@ describe SvnTransform::Transform::Newline do
|
|
41
41
|
@file.body.should == "\nabc\n"
|
42
42
|
end
|
43
43
|
|
44
|
+
it 'should skip binary files' do
|
45
|
+
input = "\r\nabc\r\n"
|
46
|
+
@file.body = input
|
47
|
+
@file.properties['svn:mime-type'] = 'application/octet-stream'
|
48
|
+
@klass.new(@file).run.should be_false
|
49
|
+
@file.body.should == "\r\nabc\r\n"
|
50
|
+
end
|
51
|
+
|
44
52
|
it 'should replace all newlines with @newline' do
|
45
53
|
input = "\r\nabc\r\n\n\n\r"
|
46
54
|
@file.body = input
|
data/lib/svn-transform.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'svn-fixture'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
STDOUT.sync = true
|
3
6
|
|
4
7
|
class SvnTransform
|
5
|
-
VERSION = '0.
|
8
|
+
VERSION = '0.2.0'
|
9
|
+
PRINT_INFO = false
|
6
10
|
|
7
11
|
class << self
|
8
12
|
# Use diff to compare two repositories (on local file system)
|
@@ -37,6 +41,62 @@ class SvnTransform
|
|
37
41
|
return false
|
38
42
|
end
|
39
43
|
end
|
44
|
+
|
45
|
+
COMPARE_DIR = '/tmp/svn-transform/compare'
|
46
|
+
COMPARE_OLD_DIR = File.join(COMPARE_DIR, 'old')
|
47
|
+
COMPARE_NEW_DIR = File.join(COMPARE_DIR, 'new')
|
48
|
+
|
49
|
+
# Compare checkouts. This takes much longer than .compare but can give a
|
50
|
+
# more accurate picture, because it is not affected by the changes in
|
51
|
+
# svn:entry properties (well, it actually just ignores the related files),
|
52
|
+
# the chance that entries are just in different order within the db file, or
|
53
|
+
# differences between the directory structure of the repo's db folders.
|
54
|
+
#
|
55
|
+
# It also has the advantage that the repositories can be remote.
|
56
|
+
#
|
57
|
+
# Note that this method will destroy existing files in the COMPARE_DIR
|
58
|
+
#
|
59
|
+
# ==== Parameters
|
60
|
+
# old_repo<String>:: URI of original (in) repository.
|
61
|
+
# new_repo<String>:: URI of generated (out) repository.
|
62
|
+
# min_rev<Integer>:: Starting revision for comparison
|
63
|
+
# max_rev<Integer>:: Ending revision for comparison
|
64
|
+
def co_compare(old_repo, new_repo, min_rev, max_rev)
|
65
|
+
FileUtils.rm_rf(COMPARE_OLD_DIR)
|
66
|
+
FileUtils.rm_rf(COMPARE_NEW_DIR)
|
67
|
+
|
68
|
+
rev = min_rev
|
69
|
+
`svn co -r#{rev} "#{old_repo}" "#{COMPARE_OLD_DIR}"`
|
70
|
+
`svn co -r#{rev} "#{new_repo}" "#{COMPARE_NEW_DIR}"`
|
71
|
+
|
72
|
+
while rev <= max_rev
|
73
|
+
co_compare_rev(rev)
|
74
|
+
rev += 1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Called by .co_compare, this checks out and compares the repositories at
|
79
|
+
# a signle revision. It prints out any differences.
|
80
|
+
#
|
81
|
+
# ==== Parameters
|
82
|
+
# rev<Integer>:: The revision to compare.
|
83
|
+
#
|
84
|
+
# ==== Returns
|
85
|
+
# True, False:: Whether the revisions are identical
|
86
|
+
def co_compare_rev(rev)
|
87
|
+
print "#{rev} " if PRINT_INFO
|
88
|
+
`svn update -r#{rev} "#{COMPARE_OLD_DIR}"`
|
89
|
+
`svn update -r#{rev} "#{COMPARE_NEW_DIR}"`
|
90
|
+
ret = `diff --brief --exclude=entries -r "#{COMPARE_OLD_DIR}" "#{COMPARE_NEW_DIR}"`
|
91
|
+
if ret.empty?
|
92
|
+
return true
|
93
|
+
else
|
94
|
+
puts "\nREVISION #{rev}"
|
95
|
+
puts ret
|
96
|
+
puts ("-" * 70)
|
97
|
+
return false
|
98
|
+
end
|
99
|
+
end
|
40
100
|
end
|
41
101
|
|
42
102
|
# Setup and SvnTransform with in (existing) repository URI, a name for the
|
@@ -116,13 +176,15 @@ class SvnTransform
|
|
116
176
|
# calls +changesets+ to do the actual work. Finally, commit the SvnFixture
|
117
177
|
# (out repo) and update its rev 0 date to match the in repo
|
118
178
|
def convert
|
119
|
-
in_repo_session = Session.new(@in_repo_uri, @in_username, @
|
179
|
+
in_repo_session = Session.new(@in_repo_uri, @in_username, @in_password)
|
120
180
|
@in_repo = in_repo_session.session
|
121
181
|
@ctx = in_repo_session.context
|
122
182
|
@out_repo = SvnFixture.repo(@out_repo_name, @out_repos_path, @out_wc_path)
|
123
183
|
|
124
184
|
# Process changesets and commit
|
185
|
+
puts "\nReading existing log..." if PRINT_INFO
|
125
186
|
changesets
|
187
|
+
puts "\nCommitting to new..." if PRINT_INFO
|
126
188
|
@out_repo.commit
|
127
189
|
|
128
190
|
# Update rev 0 date
|
@@ -142,6 +204,7 @@ class SvnTransform
|
|
142
204
|
path_renames = {}
|
143
205
|
|
144
206
|
@in_repo.log(*args) do |changes, rev_num, author, date, msg|
|
207
|
+
print "#{rev_num} " if PRINT_INFO
|
145
208
|
# Sort so that files are processed first (for benefit of PropsToYaml),
|
146
209
|
# and deletes are last
|
147
210
|
changes = changes.sort { |a,b| sort_for(a, rev_num) <=> sort_for(b, rev_num) }
|
@@ -155,6 +218,7 @@ class SvnTransform
|
|
155
218
|
out_wc_path = @out_repo.wc_path
|
156
219
|
svn_transform = self
|
157
220
|
@out_repo.revision(rev_num, msg, rev_props) do
|
221
|
+
print "#{rev_num} " if SvnTransform::PRINT_INFO
|
158
222
|
# Now go through all the changes. Setup directorie structure for each
|
159
223
|
# node. This is easier to understand, in my opinion.
|
160
224
|
|
@@ -170,6 +234,12 @@ class SvnTransform
|
|
170
234
|
|
171
235
|
# TODO Replaces
|
172
236
|
|
237
|
+
copy_from_path = nil
|
238
|
+
if change.copyfrom_path
|
239
|
+
short_from_path = path_renames[change.copyfrom_path] || change.copyfrom_path
|
240
|
+
copy_from_path = ::File.join(out_wc_path, short_from_path)
|
241
|
+
end
|
242
|
+
|
173
243
|
if change.action == 'D'
|
174
244
|
del_path = path_renames['/' + full_path.to_s] || full_path.to_s
|
175
245
|
@ctx.delete(::File.join(out_wc_path, del_path))
|
@@ -178,21 +248,11 @@ class SvnTransform
|
|
178
248
|
transform_file = ::SvnTransform::File.new(full_path, data, rev_num, rev_props)
|
179
249
|
original_path = transform_file.path
|
180
250
|
svn_transform.__send__(:process_file_transforms, transform_file)
|
181
|
-
|
182
|
-
if change.copyfrom_path
|
183
|
-
from_path = path_renames[change.copyfrom_path] || change.copyfrom_path
|
184
|
-
@ctx.cp(
|
185
|
-
::File.join(out_wc_path, from_path),
|
186
|
-
::File.join(out_wc_path, transform_file.path.to_s)
|
187
|
-
)
|
188
|
-
end
|
189
|
-
|
251
|
+
@ctx.cp(copy_from_path, ::File.join(out_wc_path, transform_file.path.to_s)) if copy_from_path
|
190
252
|
unless transform_file.skip?
|
191
253
|
parent_dir.file(transform_file.basename) do
|
192
254
|
body(transform_file.body)
|
193
|
-
transform_file.properties
|
194
|
-
prop(prop_k, prop_v) unless prop_k =~ /\Asvn:entry/
|
195
|
-
end
|
255
|
+
props(transform_file.properties)
|
196
256
|
end
|
197
257
|
# For benefit of copies
|
198
258
|
if original_path != transform_file.path
|
@@ -200,13 +260,13 @@ class SvnTransform
|
|
200
260
|
end
|
201
261
|
end
|
202
262
|
else # directory
|
263
|
+
# Paths don't change for directories, but use this for consistency
|
264
|
+
@ctx.cp(copy_from_path, ::File.join(out_wc_path, full_path.to_s)) if copy_from_path
|
203
265
|
parent_dir.dir(full_path.basename.to_s) do
|
204
266
|
data = in_repo.dir(full_path.to_s, rev_num)
|
205
267
|
transform_dir = ::SvnTransform::Dir.new(full_path, data, rev_num, rev_props, in_repo, self)
|
206
268
|
svn_transform.__send__(:process_dir_transforms, transform_dir)
|
207
|
-
transform_dir.properties
|
208
|
-
prop(prop_k, prop_v) unless prop_k =~ /\Asvn:entry/
|
209
|
-
end
|
269
|
+
props(transform_dir.properties)
|
210
270
|
end
|
211
271
|
end
|
212
272
|
end
|
@@ -246,8 +306,10 @@ class SvnTransform
|
|
246
306
|
|
247
307
|
# Return an Integer such that file changes are first, directories second
|
248
308
|
# and deleted nodes last (to minimize the chance of a Transformation being
|
249
|
-
# overridden.
|
309
|
+
# overridden. Copies are done first (so that files within a copied dir don't
|
310
|
+
# try to create the dir before the copy.
|
250
311
|
def sort_for(change, rev_num)
|
312
|
+
return -1 if change[1].copyfrom_path
|
251
313
|
return 2 if change[1].action == 'D'
|
252
314
|
return 0 if @in_repo.stat(change[0].sub(/\A\//, ''), rev_num).file?
|
253
315
|
return 1
|
@@ -24,6 +24,8 @@ class SvnTransform
|
|
24
24
|
# ==== Returns
|
25
25
|
# True, False:: indicating whether a change was made.
|
26
26
|
def run
|
27
|
+
# Skip binary files; this is probably not the best way to determine.
|
28
|
+
return false if 'application/octet-stream' == @file.properties['svn:mime-type']
|
27
29
|
body = @file.body.dup
|
28
30
|
# Replace CR and CRLF
|
29
31
|
body = all_to_lf(body)
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{svn-transform}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jared Morgan"]
|
12
|
+
s.date = %q{2009-11-02}
|
13
|
+
s.description = %q{Given a Subversion repository, svn-transform creates a new repo that is by
|
14
|
+
default identical, but allows changes to files, for example all or some of the
|
15
|
+
properties on each file can be moved from the properties to YAML prepended to
|
16
|
+
the body of the file. Primarily useful prior to conversions to other repository
|
17
|
+
types such as git.
|
18
|
+
}
|
19
|
+
s.email = %q{jmorgan@morgancreative.net}
|
20
|
+
s.extra_rdoc_files = [
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc"
|
23
|
+
]
|
24
|
+
s.files = [
|
25
|
+
".document",
|
26
|
+
".gitignore",
|
27
|
+
"LICENSE",
|
28
|
+
"README.rdoc",
|
29
|
+
"Rakefile",
|
30
|
+
"VERSION",
|
31
|
+
"examples/example_helper.rb",
|
32
|
+
"examples/fixtures/dir_props.rb",
|
33
|
+
"examples/fixtures/original.rb",
|
34
|
+
"examples/fixtures/result.rb",
|
35
|
+
"examples/svn-transform/dir_example.rb",
|
36
|
+
"examples/svn-transform/file_example.rb",
|
37
|
+
"examples/svn-transform/transform/extension_example.rb",
|
38
|
+
"examples/svn-transform/transform/newline_example.rb",
|
39
|
+
"examples/svn-transform/transform/noop_example.rb",
|
40
|
+
"examples/svn-transform/transform/props_to_yaml_example.rb",
|
41
|
+
"examples/svn-transform_example.rb",
|
42
|
+
"lib/svn-transform.rb",
|
43
|
+
"lib/svn-transform/dir.rb",
|
44
|
+
"lib/svn-transform/file.rb",
|
45
|
+
"lib/svn-transform/session.rb",
|
46
|
+
"lib/svn-transform/transform/extension.rb",
|
47
|
+
"lib/svn-transform/transform/newline.rb",
|
48
|
+
"lib/svn-transform/transform/noop.rb",
|
49
|
+
"lib/svn-transform/transform/props_to_yaml.rb",
|
50
|
+
"svn-transform.gemspec"
|
51
|
+
]
|
52
|
+
s.homepage = %q{http://github.com/jm81/svn-props-to-yaml}
|
53
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
54
|
+
s.require_paths = ["lib"]
|
55
|
+
s.rubygems_version = %q{1.3.5}
|
56
|
+
s.summary = %q{Copy Subversion repository, with the ability to alter files}
|
57
|
+
s.test_files = [
|
58
|
+
"examples/example_helper.rb",
|
59
|
+
"examples/fixtures/dir_props.rb",
|
60
|
+
"examples/fixtures/original.rb",
|
61
|
+
"examples/fixtures/result.rb",
|
62
|
+
"examples/svn-transform/dir_example.rb",
|
63
|
+
"examples/svn-transform/file_example.rb",
|
64
|
+
"examples/svn-transform/transform/extension_example.rb",
|
65
|
+
"examples/svn-transform/transform/newline_example.rb",
|
66
|
+
"examples/svn-transform/transform/noop_example.rb",
|
67
|
+
"examples/svn-transform/transform/props_to_yaml_example.rb",
|
68
|
+
"examples/svn-transform_example.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
76
|
+
s.add_runtime_dependency(%q<svn-fixture>, ["= 0.3.0"])
|
77
|
+
s.add_development_dependency(%q<spicycode-micronaut>, [">= 0"])
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<svn-fixture>, ["= 0.3.0"])
|
80
|
+
s.add_dependency(%q<spicycode-micronaut>, [">= 0"])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
s.add_dependency(%q<svn-fixture>, ["= 0.3.0"])
|
84
|
+
s.add_dependency(%q<spicycode-micronaut>, [">= 0"])
|
85
|
+
end
|
86
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: svn-transform
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jared Morgan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-02 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - "="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 0.3.0
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: spicycode-micronaut
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/svn-transform/transform/newline.rb
|
74
74
|
- lib/svn-transform/transform/noop.rb
|
75
75
|
- lib/svn-transform/transform/props_to_yaml.rb
|
76
|
+
- svn-transform.gemspec
|
76
77
|
has_rdoc: true
|
77
78
|
homepage: http://github.com/jm81/svn-props-to-yaml
|
78
79
|
licenses: []
|