svnauto 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/bin/sc +2 -10
  2. data/{lib/sc/constants.rb → bin/sva} +8 -13
  3. data/lib/{sc.rb → svnauto.rb} +13 -9
  4. data/lib/{sc → svnauto}/command.rb +8 -3
  5. data/lib/{sc → svnauto}/commands/bug.rb +5 -2
  6. data/lib/{sc → svnauto}/commands/checkout.rb +3 -1
  7. data/lib/{sc → svnauto}/commands/config.rb +18 -2
  8. data/lib/{sc → svnauto}/commands/create.rb +2 -1
  9. data/lib/{sc → svnauto}/commands/experimental.rb +19 -5
  10. data/lib/svnauto/commands/externals.rb +128 -0
  11. data/lib/{sc → svnauto}/commands/info.rb +1 -1
  12. data/lib/{sc → svnauto}/commands/list.rb +3 -1
  13. data/lib/{sc → svnauto}/commands/release.rb +39 -7
  14. data/lib/{sc → svnauto}/config_file.rb +3 -3
  15. data/lib/{sc/path.rb → svnauto/constants.rb} +24 -18
  16. data/lib/{sc → svnauto}/dispatcher.rb +11 -4
  17. data/lib/svnauto/path.rb +138 -0
  18. data/lib/{sc → svnauto}/project.rb +16 -11
  19. data/lib/{sc → svnauto}/repository.rb +2 -2
  20. data/lib/{sc → svnauto}/svn.rb +51 -10
  21. data/lib/svnauto/svn_externals.rb +187 -0
  22. data/lib/svnauto/svn_info.rb +96 -0
  23. data/lib/{sc → svnauto}/version.rb +2 -2
  24. data/test/setup.rb +24 -28
  25. data/test/test_bug.rb +10 -10
  26. data/test/test_checkout.rb +3 -3
  27. data/test/test_create.rb +3 -3
  28. data/test/test_experimental.rb +33 -18
  29. data/test/test_externals.rb +55 -0
  30. data/test/test_path.rb +148 -0
  31. data/test/test_release.rb +11 -11
  32. data/test/test_svninfo.rb +17 -0
  33. data/test/test_version.rb +16 -16
  34. metadata +35 -42
  35. data/INSTALL +0 -48
  36. data/LICENSE +0 -22
  37. data/README +0 -81
  38. data/THANKS +0 -8
  39. data/TODO +0 -8
  40. data/doc/manual.txt +0 -241
@@ -0,0 +1,96 @@
1
+ ################################################################################
2
+ #
3
+ # Copyright (C) 2006 Peter J Jones (pjones@pmade.com)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ ################################################################################
25
+ module SvnAuto
26
+ class SvnInfo
27
+ ################################################################################
28
+ # at least for now, it's eaiser to parse via regex instead of XML
29
+ ATTRIBUTES = [
30
+ [:path, /^Path:\s+(.+)$/],
31
+ [:url, /^URL:\s+(.+)$/],
32
+ [:repository_root, /^Repository\s+Root:\s+(.+)$/],
33
+ [:revision, /^Revision:\s+(\d+)$/],
34
+ [:last_change_revision, /^Last\s+Changed\s+Rev:\s+(\d+)$/],
35
+ [:last_change_date, /^Last\s+Changed\s+Date:\s+([\d-]+\s+[\d:]+(?:\s+[\d+-]+))/],
36
+ ]
37
+
38
+ ################################################################################
39
+ # put the attributes on the class
40
+ ATTRIBUTES.each {|a| attr_accessor a.first}
41
+ attr_reader :status
42
+
43
+ ################################################################################
44
+ # get info about the given path
45
+ def self.for (path, raise_on_error=false)
46
+ info = self.new
47
+ info.load_for_path(path)
48
+ raise "svn info command failed for #{path}" if !info.status and raise_on_error
49
+
50
+ info
51
+ end
52
+
53
+ ################################################################################
54
+ # create a new SvnInfo object
55
+ def initialize (attributes={})
56
+ ATTRIBUTES.each {|a| instance_variable_set("@#{a.first}", nil)}
57
+
58
+ attributes.each do |k,v|
59
+ raise "bad SvnInfo attribute given to initialize: #{k}" unless ATTRIBUTES.find {|a| a.first == k}
60
+ instance_variable_set("@#{k}", v)
61
+ end
62
+ end
63
+
64
+ ################################################################################
65
+ # parse the output of svn info
66
+ def load_for_path (path)
67
+ attributes = ATTRIBUTES.inject({}) {|m, e| m.store(e.first, nil); m}
68
+
69
+ @status = Svn.info(path) do |line|
70
+ ATTRIBUTES.each do |a|
71
+ if m = line.match(a.last)
72
+ instance_variable_set("@#{a.first}", m[1])
73
+ attributes[a.first] = true
74
+ break
75
+ end
76
+ end
77
+ end
78
+
79
+ # no need to check the status of the regexes if svn info failed
80
+ return @status unless @status
81
+
82
+ attributes.each do |k, v|
83
+ unless v
84
+ error = "please report a bug in #{Constants::ME}, I can't parse the output "
85
+ error << "of 'svn info', specifically, this regex did not match: "
86
+ error << ATTRIBUTES.find {|a| a.first == k}.last.to_s + ' '
87
+ error << "please also include the output of 'svn info #{path}'"
88
+ raise error
89
+ end
90
+ end
91
+
92
+ @status
93
+ end
94
+ end
95
+ end
96
+ ################################################################################
@@ -22,14 +22,14 @@
22
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  #
24
24
  ################################################################################
25
- module SC
25
+ module SvnAuto
26
26
  ################################################################################
27
27
  # Help deal with version numbers. Verson numbers are made up of three parts: the major,
28
28
  # minor, and macro numbers. These numbers are separated by periods:
29
29
  #
30
30
  # MAJOR.MINOR.MACRO as in 1.0.2
31
31
  #
32
- # In SC, release branches are created for MAJOR.MINOR release numbers. Release
32
+ # In SvnAuto, release branches are created for MAJOR.MINOR release numbers. Release
33
33
  # tags are used for MAJOR.MINOR.MACRO. That means that version 1.1 is open for
34
34
  # bug fixes and feature enhancements, but version 1.1.4 is locked and can't be
35
35
  # updated.
@@ -1,63 +1,59 @@
1
- require 'sc'
1
+ require 'svnauto'
2
2
  $DEBUG = true
3
3
  require 'test/unit'
4
4
 
5
- module SC
5
+ module SvnAuto
6
6
  module Test
7
7
  ################################################################################
8
8
  def setup
9
- @config_file = File.join(File.dirname(__FILE__), 'sc_config_file.yml')
10
- ENV[SC::ConfigFile::ENV_OVERRIDE] = @config_file
9
+ @config_file = File.expand_path(File.join(File.dirname(__FILE__), 'sc_config_file.yml'))
10
+ ENV[SvnAuto::ConfigFile::ENV_OVERRIDE] = @config_file
11
11
 
12
12
  @repository = File.join(File.dirname(__FILE__), 'repos')
13
13
  @sandbox = File.join(File.dirname(__FILE__), 'sandbox')
14
14
  @projfiles = File.join(File.dirname(__FILE__), 'projfiles')
15
15
 
16
- [@repository, @sandbox].each do |dir|
17
- system('mkdir', dir) or raise "mkdir #{dir}: failed"
18
- end
19
-
20
- SC::Repository.create_local(@repository)
16
+ [@repository, @sandbox].each {|d| FileUtils.mkdir(d)}
17
+ SvnAuto::Repository.create_local(@repository)
21
18
 
22
- cf = SC::ConfigFile.new
23
- cf[:repositories] << SC::Repository.new({
24
- :url => "file://#{File.expand_path(@repository)}",
19
+ cf = SvnAuto::ConfigFile.new
20
+ cf[:repositories] << SvnAuto::Repository.new({
21
+ :url => SvnAuto::Path.to_url(File.expand_path(@repository)),
25
22
  :name => "test",
26
23
  :workspace => File.expand_path(@sandbox)
27
24
  })
28
25
  cf.save
29
26
 
30
- run_sc(%W(create -f test))
31
- @project = SC::Project.new(:name => 'test', :repository => cf[:repositories].first)
27
+ run_sva(%W(create -f test))
28
+ @project = SvnAuto::Project.new(:name => 'test', :repository => cf[:repositories].first)
32
29
  end
33
30
 
34
31
  ################################################################################
35
32
  def teardown
36
33
  File.unlink(@config_file) if File.exists?(@config_file)
37
-
38
- [@repository, @sandbox].each do |dir|
39
- system('rm', '-rf', dir) or raise "rm -rf #{dir}: failed"
40
- end
34
+ [@repository, @sandbox].each {|d| FileUtils.rm_rf(d)}
41
35
  end
42
36
 
43
37
  ################################################################################
44
- def run_sc (args)
38
+ def run_sva (args)
45
39
  args[1,0] = '--force' if $add_force_flag
46
- SC::Dispatcher.new.run(%W(-rtest -ptest).concat(args))
40
+ SvnAuto::Dispatcher.new.run(%W(-rtest -ptest).concat(args))
47
41
  end
48
42
 
49
43
  ################################################################################
50
44
  def add_files (to)
51
- %W(file_one file_two).each do |file|
52
- system('cp', File.join(@projfiles, file), to)
53
- end
45
+ files = %W(file_one file_two)
46
+ files.each {|f| FileUtils.cp(File.join(@projfiles, f), to)}
54
47
 
55
- system("cd #{to}; svn add *; svn ci -m add")
48
+ Dir.chdir(to) do
49
+ files.each {|f| SvnAuto::Svn.add(f)}
50
+ SvnAuto::Svn.commit('-m', 'add')
51
+ end
56
52
  end
57
53
 
58
54
  ################################################################################
59
55
  def checkout
60
- run_sc(%W(checkout))
56
+ run_sva(%W(checkout))
61
57
  assert(File.exist?(File.join(@sandbox, 'test-trunk')))
62
58
  end
63
59
 
@@ -70,8 +66,8 @@ module SC
70
66
  ################################################################################
71
67
  def make_release (version, *extras)
72
68
  setup_project_files
73
- run_sc(['release', '-f', extras, version.to_s].flatten)
74
- assert(SC::Svn.has_path(@project.release("#{version.major_minor}/file_one")))
69
+ run_sva(['release', '-f', extras, version.to_s].flatten)
70
+ assert(SvnAuto::Svn.has_path(@project.release("#{version.major_minor}/file_one")))
75
71
  assert(File.exist?(File.join(@sandbox, "test-rel-#{version.major_minor}")))
76
72
  end
77
73
 
@@ -84,7 +80,7 @@ module SC
84
80
  yield
85
81
  $add_force_flag = false if $inside_interactive == 1
86
82
 
87
- if $inside_interactive == 1
83
+ if $inside_interactive == 1 and !SvnAuto::Path.windows?
88
84
  teardown
89
85
  setup
90
86
  yield
@@ -1,21 +1,21 @@
1
1
  require 'test/setup.rb'
2
2
 
3
3
  class TestBug < Test::Unit::TestCase
4
- include SC::Test
4
+ include SvnAuto::Test
5
5
 
6
6
  ################################################################################
7
7
  def test_create
8
8
  interactive do
9
- make_release(SC::Version.new('1.0'))
10
- run_sc(%W(bug -r 1.0 1))
11
- assert(SC::Svn.has_path(@project.branches('bug/1/file_one')))
12
- assert(SC::Svn.has_path(@project.tags('bug/PRE-1/file_one')))
9
+ make_release(SvnAuto::Version.new('1.0'))
10
+ run_sva(%W(bug -r 1.0 1))
11
+ assert(SvnAuto::Svn.has_path(@project.branches('bug/1/file_one')))
12
+ assert(SvnAuto::Svn.has_path(@project.tags('bug/PRE-1/file_one')))
13
13
 
14
14
  @should_checkout_to = File.join(@sandbox, 'test-bug-1')
15
15
  assert(File.exist?(@should_checkout_to))
16
16
 
17
17
  prop = ''
18
- SC::Svn.propget(SC::Bug::REL_BRN_PROP, @should_checkout_to) do |line|
18
+ SvnAuto::Svn.propget(SvnAuto::Bug::REL_BRN_PROP, @should_checkout_to) do |line|
19
19
  prop << line.chomp
20
20
  end
21
21
 
@@ -33,20 +33,20 @@ class TestBug < Test::Unit::TestCase
33
33
  end
34
34
 
35
35
  Dir.chdir(@should_checkout_to) do
36
- SC::Svn.commit('-m', "'testing merge'")
36
+ SvnAuto::Svn.commit('-m', "'testing merge'")
37
37
  end
38
38
 
39
- run_sc(%W(bug --close 1))
39
+ run_sva(%W(bug --close 1))
40
40
 
41
41
  has_line = false
42
- SC::Svn.cat(@project.branches('rel/1.0/file_one')) do |line|
42
+ SvnAuto::Svn.cat(@project.branches('rel/1.0/file_one')) do |line|
43
43
  has_line = true if line.match(/Line for Bug Fix 1/)
44
44
  end
45
45
 
46
46
  assert(has_line)
47
47
 
48
48
  has_line = false
49
- SC::Svn.cat("#{@project.trunk}/file_one") do |line|
49
+ SvnAuto::Svn.cat("#{@project.trunk}/file_one") do |line|
50
50
  has_line = true if line.match(/Line for Bug Fix 1/)
51
51
  end
52
52
  end
@@ -1,7 +1,7 @@
1
1
  require 'test/setup.rb'
2
2
 
3
3
  class TestCheckout < Test::Unit::TestCase
4
- include SC::Test
4
+ include SvnAuto::Test
5
5
 
6
6
  ################################################################################
7
7
  def test_trunk
@@ -11,8 +11,8 @@ class TestCheckout < Test::Unit::TestCase
11
11
  ################################################################################
12
12
  def test_release
13
13
  interactive do
14
- make_release(SC::Version.new('1.0'))
15
- run_sc(%W(checkout -r 1.0))
14
+ make_release(SvnAuto::Version.new('1.0'))
15
+ run_sva(%W(checkout -r 1.0))
16
16
  assert(File.exist?(File.join(@sandbox, 'test-rel-1.0')))
17
17
  end
18
18
  end
@@ -1,7 +1,7 @@
1
1
  require 'test/setup.rb'
2
2
 
3
3
  class TestCreate < Test::Unit::TestCase
4
- include SC::Test
4
+ include SvnAuto::Test
5
5
 
6
6
  ################################################################################
7
7
  def test_setup
@@ -12,7 +12,7 @@ class TestCreate < Test::Unit::TestCase
12
12
 
13
13
  # check the project layout
14
14
  @project.directories.each do |path|
15
- assert(SC::Svn.has_path(path))
15
+ assert(SvnAuto::Svn.has_path(path))
16
16
  end
17
17
  end
18
18
  end
@@ -21,7 +21,7 @@ class TestCreate < Test::Unit::TestCase
21
21
  # Force create a new project outside of setup
22
22
  def test_create
23
23
  interactive do
24
- run_sc(%W(create myproject))
24
+ run_sva(%W(create myproject))
25
25
  assert(File.exist?(File.join(@sandbox, 'myproject-trunk')))
26
26
  end
27
27
  end
@@ -1,15 +1,15 @@
1
1
  require 'test/setup.rb'
2
2
 
3
3
  class TestExperimental < Test::Unit::TestCase
4
- include SC::Test
4
+ include SvnAuto::Test
5
5
 
6
6
  ################################################################################
7
7
  def test_create
8
8
  interactive do
9
9
  setup_project_files
10
- run_sc(%W(exp testexp))
11
- assert(SC::Svn.has_path(@project.branches('exp/testexp/file_one')))
12
- assert(SC::Svn.has_path(@project.tags('exp/PRE-testexp/file_one')))
10
+ run_sva(%W(exp testexp))
11
+ assert(SvnAuto::Svn.has_path(@project.branches('exp/testexp/file_one')))
12
+ assert(SvnAuto::Svn.has_path(@project.tags('exp/PRE-testexp/file_one')))
13
13
  assert(File.exist?(File.join(@sandbox, 'test-exp-testexp', 'file_one')))
14
14
  end
15
15
  end
@@ -21,8 +21,8 @@ class TestExperimental < Test::Unit::TestCase
21
21
 
22
22
  ################################################################################
23
23
  add_line(File.join(@sandbox, 'test-trunk'), 'file_one', "A line that needs to be merged to the exp branch")
24
- run_sc(%W(exp --up testexp))
25
- assert(SC::Svn.has_path(@project.tags('exp/UP1-testexp')))
24
+ run_sva(%W(exp --up testexp))
25
+ assert(SvnAuto::Svn.has_path(@project.tags('exp/UP1-testexp')))
26
26
  cat_match(@project.branches('exp/testexp/file_one'), /exp branch/)
27
27
 
28
28
  ################################################################################
@@ -32,8 +32,8 @@ class TestExperimental < Test::Unit::TestCase
32
32
 
33
33
  ################################################################################
34
34
  add_line(File.join(@sandbox, 'test-trunk'), 'file_one', "Another line a-b-c-d")
35
- run_sc(%W(exp --up testexp))
36
- assert(SC::Svn.has_path(@project.tags('exp/UP2-testexp')))
35
+ run_sva(%W(exp --up testexp))
36
+ assert(SvnAuto::Svn.has_path(@project.tags('exp/UP2-testexp')))
37
37
  cat_match(@project.branches('exp/testexp/file_one'), /a-b-c-d/)
38
38
  end
39
39
  end
@@ -43,43 +43,58 @@ class TestExperimental < Test::Unit::TestCase
43
43
  interactive do
44
44
  test_up
45
45
 
46
- run_sc(%W(exp --down testexp))
47
- assert(SC::Svn.has_path(@project.tags('exp/DOWN1-testexp')))
46
+ run_sva(%W(exp --down testexp))
47
+ assert(SvnAuto::Svn.has_path(@project.tags('exp/DOWN1-testexp')))
48
48
  cat_match(File.join(@project.trunk, 'file_two'), /Hello World/)
49
49
 
50
50
  add_line(File.join(@sandbox, 'test-exp-testexp'), 'file_two', "FreeBSD")
51
- run_sc(%W(exp --down testexp))
52
- assert(SC::Svn.has_path(@project.tags('exp/DOWN2-testexp')))
51
+ run_sva(%W(exp --down testexp))
52
+ assert(SvnAuto::Svn.has_path(@project.tags('exp/DOWN2-testexp')))
53
53
  cat_match(File.join(@project.trunk, 'file_two'), /FreeBSD/)
54
54
 
55
55
  add_line(File.join(@sandbox, 'test-exp-testexp'), 'file_two', "Mac OS X")
56
- run_sc(%W(exp --down testexp))
57
- assert(SC::Svn.has_path(@project.tags('exp/DOWN3-testexp')))
56
+ run_sva(%W(exp --down testexp))
57
+ assert(SvnAuto::Svn.has_path(@project.tags('exp/DOWN3-testexp')))
58
58
  cat_match(File.join(@project.trunk, 'file_two'), /Mac OS X/)
59
59
  end
60
60
  end
61
61
 
62
+ ################################################################################
63
+ def test_branch_at_revision
64
+ interactive do
65
+ setup_project_files
66
+ trunk_info = SvnAuto::SvnInfo.for(@project.trunk, true)
67
+
68
+ add_line(File.join(@sandbox, 'test-trunk'), 'file_two', "Should only be on the trunk")
69
+ cat_match(File.join(@project.trunk, 'file_two'), /Should only be on the trunk/)
70
+
71
+ run_sva(%W(exp --revision #{trunk_info.revision} testexp))
72
+ cat_match(@project.branches('exp/testexp/file_two'), /Should only be on the trunk/, true)
73
+ end
74
+ end
75
+
62
76
  ################################################################################
63
77
  def add_line (dir, file, line)
64
78
  Dir.chdir(dir) do
65
- SC::Svn.update
79
+ SvnAuto::Svn.update
66
80
 
67
81
  File.open(file, 'a') do |file|
68
82
  file << "#{line}\n"
69
83
  end
70
84
 
71
- SC::Svn.commit('-m', 'test')
85
+ SvnAuto::Svn.commit('-m', 'test')
72
86
  end
73
87
  end
74
88
 
75
89
  ################################################################################
76
- def cat_match (file, re)
90
+ def cat_match (file, re, negate=false)
77
91
  has_line = false
78
92
 
79
- SC::Svn.cat(file) do |line|
93
+ SvnAuto::Svn.cat(file) do |line|
80
94
  has_line = true if line.match(re)
81
95
  end
82
96
 
97
+ has_line = !has_line if negate
83
98
  assert(has_line)
84
99
  end
85
100
 
@@ -0,0 +1,55 @@
1
+ require 'test/setup.rb'
2
+
3
+ class TestExternals < Test::Unit::TestCase
4
+ include SvnAuto::Test
5
+
6
+ ################################################################################
7
+ def test_lock
8
+ setup_project_files
9
+
10
+ SvnAuto::Dispatcher.new.run(%W(-rtest create -f ext))
11
+ add_files(File.join(@sandbox, 'ext-trunk'))
12
+ assert(File.exist?(File.join(@sandbox, 'ext-trunk')))
13
+
14
+ repos = File.expand_path(@repository)
15
+
16
+ Dir.chdir(File.join(@sandbox, 'test-trunk')) do
17
+ SvnAuto::Svn.propset('svn:externals', "ext #{SvnAuto::Path.to_url(repos)}/ext/trunk", '.')
18
+ SvnAuto::Svn.update
19
+ SvnAuto::Svn.commit('-m', 'adding-ext')
20
+
21
+ assert(File.directory?('ext'))
22
+ assert(File.exist?(File.join('ext', 'file_one')))
23
+ assert_equal("#{SvnAuto::Path.to_url(repos)}/ext/trunk", SvnAuto::SvnInfo.for('ext').url)
24
+
25
+ run_sva(%W(ext --lock ext))
26
+ assert(File.directory?('ext'))
27
+ assert(File.exist?(File.join('ext', 'file_one')))
28
+ assert_equal("#{SvnAuto::Path.to_url(repos)}/test/trunk/ext", SvnAuto::SvnInfo.for('ext').url)
29
+ end
30
+ end
31
+
32
+ ################################################################################
33
+ def test_unlock
34
+ # reuse the test_lock method to prepare the external for us
35
+ test_lock
36
+ repos = File.expand_path(@repository)
37
+
38
+ Dir.chdir(File.join(@sandbox, 'test-trunk')) do
39
+ run_sva(%W(ext --unlock ext))
40
+ assert_equal("#{SvnAuto::Path.to_url(repos)}/ext/trunk", SvnAuto::SvnInfo.for('ext').url)
41
+ end
42
+ end
43
+
44
+ ################################################################################
45
+ def test_fail_on_uncommitted
46
+ # reuse the test_lock method to prepare the external for us
47
+ test_lock
48
+
49
+ Dir.chdir(File.join(@sandbox, 'test-trunk')) do
50
+ File.open('file_one', 'a') {|file| file << "test\n"}
51
+ assert_raises(RuntimeError) {run_sva(%W(ext --unlock ext))}
52
+ end
53
+ end
54
+
55
+ end