svn-transform 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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