svn-transform 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jared E. Morgan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,101 @@
1
+ = svn-transform
2
+
3
+ SvnTransform allows you to recreate a Subversion repository, and make some
4
+ changes to it in the process. It is particularly designed to allow altering
5
+ the content, properties or name of files; changes at the directory level are
6
+ possible but more likely to cause errors.
7
+
8
+ The library seems to be working for my purposes, but the more moves, deletes,
9
+ copies, etc involved, the more likely this is to just miss something. In other
10
+ words, don't just throw out the old repository; you may need it.
11
+
12
+ == Use cases
13
+
14
+ Some reasons you might want to use SvnTransform:
15
+
16
+ 1. Change file extensions to suit a particular library (.txt to .markdown; See
17
+ Transforms::Extension)
18
+ 2. Move Subversion properties on files to YAML at the beginning of the file
19
+ (See Transforms::PropsToYaml), for example, before migrating to git.
20
+ 3. Change Windows style newlines to Unix style throughout repository history
21
+ (See Transforms::Newline)
22
+ 4. Remove a password from a file.
23
+ 5. Create a new repository based on another repo to which you have read but not
24
+ write and/or admin access (keep the full history of an abandoned project).
25
+
26
+ == Usage
27
+
28
+ The simplest case is a copy without any transformations:
29
+
30
+ require 'svn-transform'
31
+ transform = SvnTransform.new('svn://example.com/existing_repo', 'my_copy')
32
+ transform.convert
33
+
34
+ SvnTransform includes a method for comparing two repositories on the local
35
+ filesystem (it just runs a recursive diff with some options):
36
+
37
+ SvnTransform.compare('/path/to/existing', '/path/to/new')
38
+
39
+ I recommend (where reasonable) before you run a real transform, run a direct
40
+ copy, followed by .compare, as it might alert you that there's something about
41
+ the particular repository that SvnTransform may not handle well. There's a few
42
+ things to be aware of here:
43
+
44
+ - Subversion svn:entry properties (or some portion of them) seem to be affected
45
+ by the past history of the repository, so one difference can produce a lot
46
+ of differences in the repository.
47
+ - Folder structures may be different depending on the version of Subversion
48
+ running when the existing repo was created versus the conversion.
49
+
50
+ A basic copy can be useful, but the key element of SvnTransform is the ability
51
+ to make (some) changes throughout the entire history. A transform can be either
52
+ be a class or a block. Each file (or directory), at each revision where it is
53
+ modified in some way, is given as an SvnTransform::File (or
54
+ SvnTransform::Dir) to each transform, which can alter the basename, body
55
+ and/or properties of the file prior to its being committed to the new
56
+ Repository.
57
+
58
+ - A class should have an #initialize method which accepts a SvnTransform::File
59
+ (or Dir) as the first argument and which responds to #run.
60
+ - A block that accepts one argument (a SvnTransform::File or Dir).
61
+
62
+ See SvnTransform::File or SvnTransform::Dir for the methods available,
63
+ which include various metadata about the node/revision and the ability to make
64
+ changes prior to the commit.
65
+
66
+ Use either SvnTransform#file_transform or #dir_transform to add the transform
67
+ (they are processed in order added).
68
+
69
+ Several Transform classes are included (see classes in the SvnTransform::Transform
70
+ module). Below is an example using the Transform::Extension class and a block.
71
+
72
+ transform = SvnTransform.new('file:///svn/myrepo', 'transformed_repo')
73
+ transform.file_transform(SvnTransform::Transform::Extension, {:md => :markdown})
74
+ transform.file_transform do |file|
75
+ # Add leading newline to files name "newline.rb"
76
+ if 'newline.rb' == file.basename
77
+ file.body = "\n" + file.body
78
+ end
79
+ end
80
+ transform.convert
81
+
82
+ == Installation
83
+
84
+ Gem is hosted on gemcutter (http://gemcutter.org)
85
+
86
+ gem install svn-transform
87
+
88
+ == Note on Patches/Pull Requests
89
+
90
+ * Fork the project.
91
+ * Make your feature addition or bug fix.
92
+ * Add tests for it. This is important so I don't break it in a
93
+ future version unintentionally.
94
+ * Commit, do not mess with rakefile, version, or history.
95
+ (if you want to have your own version, that is fine but
96
+ bump version in a commit by itself I can ignore when I pull)
97
+ * Send me a pull request. Bonus points for topic branches.
98
+
99
+ == Copyright
100
+
101
+ Copyright (c) 2009 Jared E. Morgan. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "svn-transform"
8
+ gem.summary = %Q{Copy Subversion repository, with the ability to alter files}
9
+ gem.description = <<EOF
10
+ Given a Subversion repository, svn-transform creates a new repo that is by
11
+ default identical, but allows changes to files, for example all or some of the
12
+ properties on each file can be moved from the properties to YAML prepended to
13
+ the body of the file. Primarily useful prior to conversions to other repository
14
+ types such as git.
15
+ EOF
16
+ gem.email = "jmorgan@morgancreative.net"
17
+ gem.homepage = "http://github.com/jm81/svn-props-to-yaml"
18
+ gem.authors = ["Jared Morgan"]
19
+ gem.add_dependency('svn-fixture', '= 0.2.0')
20
+ gem.add_development_dependency "spicycode-micronaut"
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
27
+
28
+ require 'micronaut/rake_task'
29
+ Micronaut::RakeTask.new(:examples) do |examples|
30
+ examples.pattern = 'examples/**/*_example.rb'
31
+ examples.ruby_opts << '-rrubygems -Ilib -Iexamples'
32
+ end
33
+
34
+ Micronaut::RakeTask.new(:rcov) do |examples|
35
+ examples.pattern = 'examples/**/*_example.rb'
36
+ examples.rcov_opts = '-rrubygems -Ilib -Iexamples'
37
+ examples.rcov = true
38
+ end
39
+
40
+ task :examples => :check_dependencies
41
+
42
+ task :default => :examples
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION')
47
+ version = File.read('VERSION')
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "svn-props-to-yaml #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,31 @@
1
+ require 'micronaut'
2
+ require 'svn-transform'
3
+
4
+ def not_in_editor?
5
+ !(ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM'))
6
+ end
7
+
8
+ Micronaut.configure do |c|
9
+ c.color_enabled = not_in_editor?
10
+ c.filter_run :focused => true
11
+ end
12
+
13
+ def (SvnTransform::File).example
14
+ SvnTransform::File.new(
15
+ '/path/to/file.txt', # Actually a Pathname
16
+ ['body of file', {'prop:svn' => 'property value'}],
17
+ 10,
18
+ {'svn:author' => 'me'}
19
+ )
20
+ end
21
+
22
+ def (SvnTransform::Dir).example
23
+ SvnTransform::Dir.new(
24
+ '/path/to/dir', # Actually a Pathname
25
+ [{'entry.txt' => nil}, {'prop:svn' => 'property value'}],
26
+ 10,
27
+ {'svn:author' => 'me'},
28
+ :repos, # Actually a Svn::Ra::Session
29
+ :fixture_dir
30
+ )
31
+ end
@@ -0,0 +1,29 @@
1
+ # For text PropsToYaml for Directories
2
+
3
+ SvnFixture.repo('dir_props') do
4
+ revision(1, 'create dirs') do
5
+ dir 'noprops'
6
+
7
+ dir 'svnprops' do
8
+ prop 'one', 'o'
9
+ prop 'two', 't'
10
+ end
11
+
12
+ dir 'yamlprops' do
13
+ file 'meta.yml' do
14
+ body "---\none: yaml\n"
15
+ end
16
+ end
17
+
18
+ dir 'bothprops' do
19
+ prop 'one', 'o'
20
+
21
+ file 'meta.yml' do
22
+ body "---\none: yaml\ntwo: yaml"
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ SvnFixture.repo('dir_props').commit
@@ -0,0 +1,86 @@
1
+ # Original repository for conversion
2
+
3
+ SvnFixture.repo('original') do
4
+ revision(1, 'Create articles directory',
5
+ :date => Time.parse("2009-01-01")) do
6
+ dir 'articles'
7
+ end
8
+
9
+ revision 2, 'Create articles about computers and philosophy', :date => '2009-01-02' do
10
+ dir 'articles' do
11
+ prop 'ws:title', 'Articles'
12
+
13
+ file 'philosophy.txt' do
14
+ prop 'ws:title', 'Philosophy'
15
+ prop 'ws:published_at', '2009-07-01 12:00:00'
16
+ body 'My philosophy is to eat a lot of salsa!'
17
+ end
18
+
19
+ file 'computers.txt' do
20
+ prop 'ws:title', 'Computers'
21
+ prop 'ws:published_at', '2009-07-01 12:00:00'
22
+ body 'Computers do not like salsa so much.'
23
+ end
24
+ end
25
+ end
26
+
27
+ revision 3, 'Change text of articles, with different newline styles', :author => "author", :date => '2009-01-03' do
28
+ dir 'articles' do
29
+ file 'philosophy.txt' do
30
+ body "My philosophy is \n\nto eat a lot of salsa!\n"
31
+ end
32
+
33
+ file 'computers.txt' do
34
+ body "Computers do not \r\n\r\nlike salsa so much."
35
+ end
36
+
37
+ file 'old-apple.txt' do
38
+ body "One line.\r Two line.\r"
39
+ end
40
+ end
41
+ end
42
+
43
+ revision 4, 'Add some YAML props', :date => '2009-01-04' do
44
+ dir 'articles' do
45
+ file 'philosophy.txt' do
46
+ body "---\ntitle: New Philosophy\n---\n\nMy philosophy is \n\nto eat a lot of salsa!\n"
47
+ end
48
+
49
+ file 'computers.txt' do
50
+ body "---\r\neol: CRLF\r\n\---\r\n\r\ncomputers do not \r\nlike salsa so much."
51
+ end
52
+ end
53
+ end
54
+
55
+ revision 5, 'Add a directory property', :date => '2009-01-05' do
56
+ dir 'articles' do
57
+ prop 'ws:name', 'Articles'
58
+ end
59
+ end
60
+
61
+ revision 6, 'Add property with different prefix', :date => '2009-01-06' do
62
+ dir 'articles' do
63
+ file 'computers.txt' do
64
+ prop 'alt:title', 'Computers'
65
+ end
66
+ end
67
+ end
68
+
69
+ revision 7, 'Moves and copies', :date => '2009-01-07' do
70
+ dir 'articles' do
71
+ move 'philosophy.txt', 'phil.txt'
72
+ copy 'computers.txt', 'computations.txt'
73
+ end
74
+ end
75
+
76
+ revision 8, 'Revise properties', :date => '2009-01-08' do
77
+ dir 'articles' do
78
+ file 'computers.txt' do
79
+ prop 'ws:published_at', '2009-08-01 12:00:00'
80
+ prop 'alt:title', 'Computers'
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ SvnFixture.repo('original').commit
@@ -0,0 +1,105 @@
1
+ =begin
2
+ Expected result. Transform are
3
+ @transform.file_transform(
4
+ SvnTransform::Transform::PropsToYaml,
5
+ [['ws:tags', 'topics'], [/\Aws:(.*)\Z/, '\1']]
6
+ )
7
+ @transform.dir_transform(
8
+ SvnTransform::Transform::PropsToYaml,
9
+ [['ws:tags', 'topics'], [/\Aws:(.*)\Z/, '\1']] # TODO tags aren't tested
10
+ )
11
+ @transform.file_transform(
12
+ SvnTransform::Transform::Newline
13
+ )
14
+ @transform.file_transform(
15
+ SvnTransform::Transform::Extension,
16
+ :txt => :md
17
+ )
18
+ =end
19
+
20
+ SvnFixture.repo('result') do
21
+ revision(1, 'Create articles directory',
22
+ :date => Time.parse("2009-01-01")) do
23
+ dir 'articles'
24
+ end
25
+
26
+ revision 2, 'Create articles about computers and philosophy', :date => '2009-01-02' do
27
+ dir 'articles' do
28
+ file 'meta.yml' do
29
+ body "--- \ntitle: Articles\n"
30
+ end
31
+
32
+ file 'philosophy.md' do
33
+ body "--- \ntitle: Philosophy\npublished_at: 2009-07-01 12:00:00\n\---\n\nMy philosophy is to eat a lot of salsa!"
34
+ end
35
+
36
+ file 'computers.md' do
37
+ body "--- \ntitle: Computers\npublished_at: 2009-07-01 12:00:00\n---\n\nComputers do not like salsa so much."
38
+ end
39
+ end
40
+ end
41
+
42
+ revision 3, 'Change text of articles, with different newline styles', :author => "author", :date => '2009-01-03' do
43
+ dir 'articles' do
44
+ file 'philosophy.md' do
45
+ body "--- \ntitle: Philosophy\npublished_at: 2009-07-01 12:00:00\n\---\n\nMy philosophy is \n\nto eat a lot of salsa!\n"
46
+ end
47
+
48
+ file 'computers.md' do
49
+ body "--- \ntitle: Computers\npublished_at: 2009-07-01 12:00:00\n---\n\nComputers do not \n\nlike salsa so much."
50
+ end
51
+
52
+ file 'old-apple.md' do
53
+ body "One line.\n Two line.\n"
54
+ end
55
+ end
56
+ end
57
+
58
+ revision 4, 'Add some YAML props', :date => '2009-01-04' do
59
+ dir 'articles' do
60
+ file 'philosophy.md' do
61
+ # Subversion property overrides new yaml prop (TODO is this ideal?)
62
+ body "--- \ntitle: Philosophy\npublished_at: 2009-07-01 12:00:00\n---\n\nMy philosophy is \n\nto eat a lot of salsa!\n"
63
+ end
64
+
65
+ file 'computers.md' do
66
+ body "--- \ntitle: Computers\neol: CRLF\npublished_at: 2009-07-01 12:00:00\n---\n\ncomputers do not \nlike salsa so much."
67
+ end
68
+ end
69
+ end
70
+
71
+ revision 5, 'Add a directory property', :date => '2009-01-05' do
72
+ dir 'articles' do
73
+ file 'meta.yml' do
74
+ body "--- \nname: Articles\ntitle: Articles\n"
75
+ end
76
+ end
77
+ end
78
+
79
+ revision 6, 'Add property with different prefix', :date => '2009-01-06' do
80
+ dir 'articles' do
81
+ file 'computers.md' do
82
+ prop 'alt:title', 'Computers'
83
+ body "--- \ntitle: Computers\neol: CRLF\npublished_at: 2009-07-01 12:00:00\n---\n\ncomputers do not \nlike salsa so much."
84
+ end
85
+ end
86
+ end
87
+
88
+ revision 7, 'Moves and copies', :date => '2009-01-07' do
89
+ dir 'articles' do
90
+ move 'philosophy.md', 'phil.md'
91
+ copy 'computers.md', 'computations.md'
92
+ end
93
+ end
94
+
95
+ revision 8, 'Revise properties', :date => '2009-01-08' do
96
+ dir 'articles' do
97
+ file 'computers.md' do
98
+ prop 'alt:title', 'Computers'
99
+ body "--- \ntitle: Computers\neol: CRLF\npublished_at: 2009-08-01 12:00:00\n---\n\ncomputers do not \nlike salsa so much."
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ SvnFixture.repo('result').commit