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 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.2.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
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
@@ -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
@@ -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.1.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, @out_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.each_pair do |prop_k, prop_v|
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.each_pair do |prop_k, prop_v|
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.1.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-10-28 00:00:00 -05:00
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.2.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: []