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 +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
|