svn-transform 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +101 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/examples/example_helper.rb +31 -0
- data/examples/fixtures/dir_props.rb +29 -0
- data/examples/fixtures/original.rb +86 -0
- data/examples/fixtures/result.rb +105 -0
- data/examples/svn-transform/dir_example.rb +56 -0
- data/examples/svn-transform/file_example.rb +71 -0
- data/examples/svn-transform/transform/extension_example.rb +48 -0
- data/examples/svn-transform/transform/newline_example.rb +51 -0
- data/examples/svn-transform/transform/noop_example.rb +15 -0
- data/examples/svn-transform/transform/props_to_yaml_example.rb +137 -0
- data/examples/svn-transform_example.rb +148 -0
- data/lib/svn-transform.rb +264 -0
- data/lib/svn-transform/dir.rb +65 -0
- data/lib/svn-transform/file.rb +79 -0
- data/lib/svn-transform/session.rb +62 -0
- data/lib/svn-transform/transform/extension.rb +41 -0
- data/lib/svn-transform/transform/newline.rb +50 -0
- data/lib/svn-transform/transform/noop.rb +28 -0
- data/lib/svn-transform/transform/props_to_yaml.rb +134 -0
- metadata +115 -0
data/.document
ADDED
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
|