redcar 0.6.1 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/CHANGES +26 -0
  2. data/README.md +17 -31
  3. data/Rakefile +1 -1
  4. data/bin/redcar +1 -1
  5. data/lib/redcar.rb +8 -4
  6. data/lib/redcar/installer.rb +2 -1
  7. data/plugins/application/features/step_definitions/dialog_steps.rb +5 -0
  8. data/plugins/application/features/step_definitions/tree_steps.rb +1 -1
  9. data/plugins/application/features/support/env.rb +38 -17
  10. data/plugins/application/lib/application.rb +4 -0
  11. data/plugins/application/lib/application/command.rb +8 -2
  12. data/plugins/application/lib/application/command/executor.rb +37 -8
  13. data/plugins/application/lib/application/command/history.rb +3 -3
  14. data/plugins/application/lib/application/menu.rb +4 -0
  15. data/plugins/application/lib/application/menu/item.rb +9 -1
  16. data/plugins/application/lib/application/tab.rb +11 -0
  17. data/plugins/application/spec/application/command/executor_spec.rb +3 -3
  18. data/plugins/application/spec/application/command_spec.rb +24 -0
  19. data/plugins/application/spec/spec_helper.rb +1 -0
  20. data/plugins/application_swt/lib/application_swt.rb +27 -24
  21. data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +4 -33
  22. data/plugins/application_swt/lib/application_swt/dialogs/input_dialog.rb +46 -0
  23. data/plugins/application_swt/lib/application_swt/dialogs/text_and_file_dialog.rb +118 -0
  24. data/plugins/application_swt/lib/application_swt/icon.rb +37 -0
  25. data/plugins/application_swt/lib/application_swt/menu.rb +8 -3
  26. data/plugins/application_swt/lib/application_swt/tab.rb +6 -3
  27. data/plugins/application_swt/lib/application_swt/treebook.rb +29 -31
  28. data/plugins/application_swt/lib/swt/graphics_utils.rb +170 -0
  29. data/plugins/application_swt/lib/swt/vtab_folder.rb +125 -0
  30. data/plugins/application_swt/lib/swt/vtab_item.rb +69 -0
  31. data/plugins/application_swt/lib/swt/vtab_label.rb +84 -0
  32. data/plugins/auto_indenter/lib/auto_indenter.rb +4 -2
  33. data/plugins/core/lib/core/controller.rb +18 -0
  34. data/plugins/declarations/lib/declarations.rb +1 -1
  35. data/plugins/document_search/lib/document_search.rb +8 -6
  36. data/plugins/document_search/lib/document_search/replace.rb +51 -31
  37. data/plugins/document_search/lib/document_search/search_and_replace.rb +12 -11
  38. data/plugins/edit_view/features/step_definitions/editing_steps.rb +33 -17
  39. data/plugins/edit_view/lib/edit_view.rb +100 -21
  40. data/plugins/edit_view/lib/edit_view/actions/arrow_keys.rb +34 -11
  41. data/plugins/edit_view/lib/edit_view/actions/deletion.rb +10 -0
  42. data/plugins/edit_view/lib/edit_view/command.rb +5 -1
  43. data/plugins/edit_view/lib/edit_view/document.rb +8 -3
  44. data/plugins/edit_view/lib/edit_view/document/command.rb +15 -1
  45. data/plugins/edit_view/lib/edit_view/document/controller.rb +9 -0
  46. data/plugins/edit_view/lib/edit_view/document/history.rb +41 -0
  47. data/plugins/edit_view/lib/edit_view/tab_settings.rb +1 -11
  48. data/plugins/edit_view_swt/lib/edit_view_swt.rb +150 -4
  49. data/plugins/edit_view_swt/lib/edit_view_swt/document.rb +1 -1
  50. data/plugins/edit_view_swt/vendor/java-mateview.rb +1 -1
  51. data/plugins/find-in-project/lib/find_in_project.rb +7 -5
  52. data/plugins/html_view/features/step_definitions/html_view_steps.rb +2 -2
  53. data/plugins/line_tools/features/step_definitions/line_tools_steps.rb +0 -1
  54. data/plugins/line_tools/lib/line_tools.rb +7 -9
  55. data/plugins/macros/features/block_selection_in_macros.feature +48 -0
  56. data/plugins/macros/features/predictive_macros.feature +79 -0
  57. data/plugins/macros/features/record_and_run_macro.feature +87 -0
  58. data/plugins/macros/features/step_definitions/macro_steps.rb +66 -0
  59. data/plugins/macros/features/step_definitions/prediction_steps.rb +8 -0
  60. data/plugins/macros/features/support/env.rb +2 -0
  61. data/plugins/macros/lib/macros.rb +167 -0
  62. data/plugins/macros/lib/macros/action_sequence.rb +30 -0
  63. data/plugins/macros/lib/macros/commands.rb +108 -0
  64. data/plugins/macros/lib/macros/macro.rb +37 -0
  65. data/plugins/macros/lib/macros/manager_controller.rb +67 -0
  66. data/plugins/macros/lib/macros/predictive/document_controller.rb +69 -0
  67. data/plugins/macros/lib/macros/predictive/sequence_finder.rb +112 -0
  68. data/plugins/macros/plugin.rb +9 -0
  69. data/plugins/macros/spec/macros/predictive/sequence_finder_spec.rb +142 -0
  70. data/plugins/macros/spec/spec_helper.rb +6 -0
  71. data/plugins/macros/views/macro_manager.html.erb +86 -0
  72. data/plugins/outline_view/lib/outline_view.rb +1 -1
  73. data/plugins/project/lib/project/commands.rb +2 -2
  74. data/plugins/redcar/redcar.rb +37 -46
  75. data/plugins/repl/lib/repl.rb +4 -4
  76. data/plugins/runnables/features/command_tree.feature +1 -1
  77. data/plugins/runnables/features/parameter_input.feature +42 -0
  78. data/plugins/runnables/features/step_definitions/runnable_steps.rb +6 -0
  79. data/plugins/runnables/features/support/env.rb +28 -8
  80. data/plugins/runnables/lib/runnables.rb +35 -206
  81. data/plugins/runnables/lib/runnables/commands.rb +65 -0
  82. data/plugins/runnables/lib/runnables/tree_mirror/nodes/runnable.rb +62 -0
  83. data/plugins/runnables/lib/runnables/tree_mirror/nodes/runnable_group.rb +59 -0
  84. data/plugins/runnables/lib/runnables/tree_mirror/nodes/runnable_type_group.rb +32 -0
  85. data/plugins/runnables/lib/runnables/tree_mirror/tree_controller.rb +41 -0
  86. data/plugins/runnables/lib/runnables/tree_mirror/tree_mirror.rb +61 -0
  87. data/plugins/scm/lib/scm.rb +78 -45
  88. data/plugins/scm/lib/scm/commands.rb +18 -4
  89. data/plugins/scm/lib/scm/model.rb +54 -41
  90. data/plugins/scm_svn/LICENSE +48 -0
  91. data/plugins/scm_svn/features/add_and_commit.feature +18 -0
  92. data/plugins/scm_svn/features/checkout.feature +5 -0
  93. data/plugins/scm_svn/features/edit_and_index.feature +12 -0
  94. data/plugins/scm_svn/features/ignore_files.feature +14 -0
  95. data/plugins/scm_svn/features/merge.feature +34 -0
  96. data/plugins/scm_svn/features/resolve_conflict.feature +23 -0
  97. data/plugins/scm_svn/features/revert_and_delete.feature +21 -0
  98. data/plugins/scm_svn/features/step_definitions/branch_and_merge_steps.rb +27 -0
  99. data/plugins/scm_svn/features/step_definitions/checkout_steps.rb +25 -0
  100. data/plugins/scm_svn/features/step_definitions/edit_and_index_steps.rb +50 -0
  101. data/plugins/scm_svn/features/step_definitions/scm_svn_steps.rb +57 -0
  102. data/plugins/scm_svn/features/support/env.rb +74 -0
  103. data/plugins/scm_svn/features/switch_branches.feature +53 -0
  104. data/plugins/scm_svn/features/update.feature +16 -0
  105. data/plugins/scm_svn/lib/scm_svn.rb +423 -9
  106. data/plugins/scm_svn/lib/scm_svn/change.rb +116 -0
  107. data/plugins/swt/lib/swt.rb +0 -15
  108. data/plugins/swt/lib/swt/cucumber_patches.rb +2 -37
  109. data/plugins/swt/lib/swt/cucumber_runner.rb +1 -0
  110. data/plugins/swt/lib/swt/full_swt.rb +2 -0
  111. data/plugins/textmate/vendor/redcar-bundles/Bundles/Clojure.tmbundle/Syntaxes/Clojure.tmLanguage +14 -2
  112. data/plugins/todo_list/lib/todo_list/todo_controller.rb +1 -1
  113. data/plugins/todo_list/views/default.css +50 -0
  114. data/plugins/todo_list/views/index.html.erb +5 -16
  115. data/plugins/todo_list/views/redcar_small_icon.png +0 -0
  116. data/plugins/tree_view_swt/lib/tree_view_swt.rb +14 -33
  117. data/plugins/view_shortcuts/views/default.css +31 -0
  118. data/plugins/view_shortcuts/views/index.html.erb +26 -16
  119. data/plugins/view_shortcuts/views/redcar_small_icon.png +0 -0
  120. data/{plugins/runnables → share}/icons/cog.png +0 -0
  121. data/share/icons/folder-gear-emblem.png +0 -0
  122. data/share/icons/folder-gear.png +0 -0
  123. data/share/icons/folder-open-small-gears.png +0 -0
  124. metadata +59 -5
@@ -0,0 +1,27 @@
1
+ Given /^I will open "([^"]*)" branch as a new project$/ do |branch_name|
2
+ path = parse_branch_path(branch_name)
3
+ if path
4
+ Redcar.gui.dialog_adapter.set(:open_directory, path)
5
+ @svn_module = Redcar::Scm::Subversion::Manager.new
6
+ @svn_module.load(path)
7
+ end
8
+ end
9
+
10
+ When /^I switch to "([^"]*)" branch$/ do |branch_name|
11
+ path = parse_branch_path(branch_name)
12
+ Redcar.gui.dialog_adapter.set(:open_directory, path) if path
13
+ svn_module.switch!(branch_name)
14
+ svn_module.repository?(path).should == true
15
+ end
16
+
17
+ When /^I merge the "([^"]*)" branch$/ do |branch_name|
18
+ path = parse_branch_path(branch_name)
19
+ svn_module.merge!(branch_name)
20
+ end
21
+
22
+ Then /^I should see "([^"]*)" in "([^"]*)" branch$/ do |files, branch_name|
23
+ path = parse_branch_path(branch_name)
24
+ files.split(",").each {|f|
25
+ File.exist?(path + "/#{f}").should == true
26
+ }
27
+ end
@@ -0,0 +1,25 @@
1
+ #TODO: find a way to test the http and svn protocols
2
+ When /^I checkout "([^"]*)" in a local repository$/ do |subdirectory|
3
+ path = create_dir(working_copy)
4
+ path = path + "#{subdirectory}" if subdirectory
5
+ File.mkdir_p(path) unless File.exist?(path)
6
+ svn_module.load(path)
7
+ svn_module.remote_init(svn_repository_url,path)
8
+ end
9
+
10
+ When /^I checkout a local repository$/ do
11
+ path = create_dir(working_copy)
12
+ svn_module.load(path)
13
+ svn_module.remote_init(svn_repository_url,path)
14
+ end
15
+
16
+ Then /^I should have a working copy$/ do
17
+ svn_module.repository?(get_dir(working_copy)).should == true
18
+ end
19
+
20
+ Then /^if I checkout to a new working copy, it should have "([^"]*)" files$/ do |file_count|
21
+ path = create_dir(working_copy_2)
22
+ svn_module_2.load(path)
23
+ svn_module_2.remote_init(svn_repository_url,path)
24
+ repo_file_count(svn_module_2.path).should == file_count.to_i
25
+ end
@@ -0,0 +1,50 @@
1
+ When /^I add "([^"]*)" to the index$/ do |files|
2
+ files.split(",").each do |file|
3
+ svn_module.index_add(File.new(get_dir(working_copy) + "/#{file}"))
4
+ end
5
+ end
6
+
7
+ When /^I create a wc file named "([^"]*)"$/ do |files|
8
+ files.split(",").each do |file|
9
+ FileUtils.touch(get_dir(working_copy) + "/#{file}")
10
+ end
11
+ end
12
+
13
+ When /^I create a wc directory named "([^"]*)"$/ do |dirs|
14
+ dirs.split(",").each do |dir|
15
+ FileUtils.mkdir_p get_dir(working_copy) + "/#{dir}"
16
+ end
17
+ end
18
+
19
+ Then /^there should be "([^"]*)" unindexed files and "([^"]*)" indexed files$/ do |ucount, count|
20
+ svn_module.unindexed_changes.length.should == ucount.to_i
21
+ svn_module.indexed_changes.length.should == count.to_i
22
+ end
23
+
24
+ When /^I replace "([^"]*)" contents(| in the new copy) with "([^"]*)"$/ do |file,repo,text|
25
+ if repo == ""
26
+ File.open(get_dir(working_copy) + "/#{file}", 'w') do |f|
27
+ f.rewind
28
+ f.truncate(0)
29
+ f.puts text
30
+ end
31
+ else
32
+ File.open(get_dir(working_copy_2) + "/#{file}", 'w') do |f|
33
+ f.rewind
34
+ f.truncate(0)
35
+ f.puts text
36
+ end
37
+ end
38
+ end
39
+
40
+ Then /^the contents of wc file "([^"]*)"(| in the new copy) should be "([^"]*)"$/ do |file,repo,text|
41
+ if repo == " in the new copy"
42
+ File.read(get_dir(working_copy_2) + "/#{file}").rstrip.should == text
43
+ else
44
+ File.read(get_dir(working_copy) + "/#{file}").rstrip.should == text
45
+ end
46
+ end
47
+
48
+ #Then /^the contents of wc file "([^"]*)" in the new copy should be "([^"]*)"$/ do |file,text|
49
+ # File.read(get_dir(working_copy_2) + "/#{file}").rstrip.should == text
50
+ #end
@@ -0,0 +1,57 @@
1
+
2
+ When /^I commit my changes(| in the new copy) with message "([^"]*)"$/ do |repo,message|
3
+ if repo == ""
4
+ svn_module.commit!(message)
5
+ else
6
+ svn_module_2.commit!(message)
7
+ end
8
+ end
9
+
10
+ When /^I ignore "([^"]*)"$/ do |file|
11
+ svn_module.index_ignore(File.new(svn_module.path + "/#{file}"))
12
+ end
13
+
14
+ When /^I ignore "([^"]*)" files$/ do |extension|
15
+ svn_module.index_ignore_all(extension,nil)
16
+ end
17
+
18
+ When /^I wc delete "([^"]*)"$/ do |file|
19
+ path = svn_module.path + "/#{file}"
20
+ svn_module.index_delete(Redcar::Scm::Subversion::Change.new(path,:normal,[],nil))
21
+ end
22
+
23
+ When /^I revert "([^"]*)"$/ do |file|
24
+ svn_module.index_revert(File.new(svn_module.path+"/#{file}"))
25
+ end
26
+
27
+ Then /^if I update my(| new) working copy, it should have "([^"]*)" files$/ do |repo,file_count|
28
+ if repo == " new"
29
+ svn_module_2.pull!
30
+ repo_file_count(svn_module_2.path).should == file_count.to_i
31
+ else
32
+ svn_module.pull!
33
+ repo_file_count(svn_module.path).should == file_count.to_i
34
+ end
35
+ end
36
+
37
+ Then /^there should be "([^"]*)" conflicted files(| in the new copy)$/ do |file_count,repo|
38
+ if repo == ""
39
+ mod = svn_module
40
+ else
41
+ mod = svn_module_2
42
+ end
43
+ changes = []
44
+ mod.indexed_changes.map {|i| changes << i if i.status[0] == :unmerged}
45
+ changes.length.should == file_count.to_i
46
+ end
47
+
48
+ When /^and I resolve "([^"]*)" conflicts(| in the new copy)$/ do |file,repo|
49
+ if repo == ""
50
+ mod = svn_module
51
+ else
52
+ mod = svn_module_2
53
+ end
54
+ changes = []
55
+ mod.indexed_changes.map {|i| changes << i if i.status[0] == :unmerged}
56
+ changes.each {|c| mod.resolve_conflict(c) if File.basename(c.path) == file}
57
+ end
@@ -0,0 +1,74 @@
1
+ RequireSupportFiles File.dirname(__FILE__) + "/../../../application/features/"
2
+ RequireSupportFiles File.dirname(__FILE__) + "/../../../project/features/"
3
+ RequireSupportFiles File.dirname(__FILE__) + "/../../../runnables/features/"
4
+ require File.join(Redcar.asset_dir, "svnkit")
5
+ require 'java'
6
+ import 'org.tmatesoft.svn.core.io.SVNRepositoryFactory'
7
+
8
+ def fixtures
9
+ File.expand_path(File.dirname(__FILE__) + "/../fixtures")
10
+ end
11
+
12
+ # minus 3 for '.' and '..' and '.svn'
13
+ def repo_file_count(path)
14
+ (Dir.entries(path).size - 3).to_i
15
+ end
16
+
17
+ def parse_branch_path(branch_name)
18
+ if branch_name == 'trunk'
19
+ svn_module.trunk_path
20
+ else
21
+ svn_module.branch_path + "/#{branch_name}"
22
+ end
23
+ end
24
+
25
+ def svn_repository
26
+ "#{fixtures}/test_repo"
27
+ end
28
+
29
+ def working_copy
30
+ "my_repo"
31
+ end
32
+
33
+ def working_copy_2
34
+ "my_repo_2"
35
+ end
36
+
37
+ def svn_repository_url
38
+ "file://" + File.expand_path(svn_repository)
39
+ end
40
+
41
+ def create_dir(path)
42
+ FileUtils.mkdir_p "#{fixtures}/#{path}"
43
+ File.expand_path("#{fixtures}/#{path}")
44
+ end
45
+
46
+ def get_dir(path)
47
+ File.expand_path("#{fixtures}/#{path}")
48
+ end
49
+
50
+ def svn_module
51
+ @svn_module ||= Redcar::Scm::Subversion::Manager.new
52
+ end
53
+
54
+ def svn_module_2
55
+ @svn_module_2 ||= Redcar::Scm::Subversion::Manager.new
56
+ end
57
+
58
+ def reset_fixtures
59
+ FileUtils.rm_rf fixtures
60
+ FileUtils.mkdir_p fixtures
61
+ FileUtils.mkdir_p File.dirname(svn_repository)
62
+ SVNRepositoryFactory.createLocalRepository(Java::JavaIo::File.new(svn_repository),true,false)
63
+ svn_module
64
+ end
65
+
66
+ Before do
67
+ @svn_module = nil
68
+ reset_fixtures
69
+ end
70
+
71
+ After do
72
+ FileUtils.rm_rf fixtures
73
+ @svn_module = nil
74
+ end
@@ -0,0 +1,53 @@
1
+ Feature: Opening other branches as new projects
2
+
3
+ Scenario: Opening a branch from trunk
4
+ When I checkout a local repository
5
+ And I create a wc directory named "trunk,branches,branches/version1,branches/version2"
6
+ And I create a wc file named "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt"
7
+ And I add "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt" to the index
8
+ And I commit my changes with message "Initial commit"
9
+ Given I will open "trunk" branch as a new project
10
+ When I open a directory
11
+ And I note the number of windows
12
+ And I switch to "version1" branch
13
+ Then I should see 1 more window
14
+ And the window should have title "version1"
15
+
16
+ Scenario: Opening a branch from another branch
17
+ When I checkout a local repository
18
+ And I create a wc directory named "trunk,branches,branches/version1,branches/version2"
19
+ And I create a wc file named "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt"
20
+ And I add "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt" to the index
21
+ And I commit my changes with message "Initial commit"
22
+ Given I will open "version1" branch as a new project
23
+ When I open a directory
24
+ And I note the number of windows
25
+ And I switch to "version2" branch
26
+ Then I should see 1 more window
27
+ And the window should have title "version2"
28
+
29
+ Scenario: Opening trunk from a branch
30
+ When I checkout a local repository
31
+ And I create a wc directory named "trunk,branches,branches/version1,branches/version2"
32
+ And I create a wc file named "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt"
33
+ And I add "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt" to the index
34
+ And I commit my changes with message "Initial commit"
35
+ Given I will open "version1" branch as a new project
36
+ When I open a directory
37
+ And I note the number of windows
38
+ And I switch to "trunk" branch
39
+ Then I should see 1 more window
40
+ And the window should have title "trunk"
41
+
42
+ Scenario: Attempting to open the same branch from the branching dialog
43
+ When I checkout a local repository
44
+ And I create a wc directory named "trunk,branches,branches/version1,branches/version2"
45
+ And I create a wc file named "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt"
46
+ And I add "trunk/a.txt,branches/version1/b.txt,branches/version2/c.txt" to the index
47
+ And I commit my changes with message "Initial commit"
48
+ Given I will open "version1" branch as a new project
49
+ When I open a directory
50
+ And I note the number of windows
51
+ And I switch to "version1" branch
52
+ Then I should see 0 more windows
53
+ And the window should have title "version1"
@@ -0,0 +1,16 @@
1
+ Feature: Updating a working copy from a remote repository
2
+
3
+ Scenario: Updating a working copy
4
+ When I checkout a local repository
5
+ And I create a wc file named "foo.rb"
6
+ And I replace "foo.rb" contents with "Never gonna make you cry"
7
+ And I add "foo.rb" to the index
8
+ And I commit my changes with message "Hark! This is a commit."
9
+ Then if I checkout to a new working copy, it should have "1" files
10
+ And the contents of wc file "foo.rb" in the new copy should be "Never gonna make you cry"
11
+ When I replace "foo.rb" contents with "Never gonna say goodbye"
12
+ And I create a wc file named "bar.rb"
13
+ And I add "bar.rb" to the index
14
+ And I commit my changes with message "Yarr! This is another commit."
15
+ Then if I update my new working copy, it should have "2" files
16
+ And the contents of wc file "foo.rb" in the new copy should be "Never gonna say goodbye"
@@ -1,30 +1,444 @@
1
1
 
2
+ require 'java'
3
+ require 'scm_svn/change'
4
+ require File.join(Redcar.asset_dir,"svnkit")
5
+
2
6
  module Redcar
3
7
  module Scm
4
8
  module Subversion
5
9
  class Manager
6
10
  include Redcar::Scm::Model
7
-
11
+ attr_reader :path
12
+ include_package 'org.tmatesoft.svn.core.wc'
13
+ include_package 'org.tmatesoft.svn.core'
14
+ import 'org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory'
15
+ import 'org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl'
16
+ import 'org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory'
17
+ import 'org.tmatesoft.svn.core.io.SVNRepositoryFactory'
18
+
19
+ def client_manager
20
+ @manager ||= begin
21
+ m = SVNClientManager.newInstance()
22
+ DAVRepositoryFactory.setup()
23
+ SVNRepositoryFactoryImpl.setup()
24
+ FSRepositoryFactory.setup()
25
+ m
26
+ end
27
+ end
28
+
29
+ def repository_type
30
+ "subversion"
31
+ end
32
+
8
33
  def self.scm_module
9
34
  Redcar::Scm::Subversion::Manager
10
35
  end
11
-
36
+
12
37
  def self.supported?
13
- # not implemented, and hence never supported
14
- puts " Subversion support is currently unimplemented" if debug
15
- false
38
+ true
39
+ end
40
+
41
+ def load(path)
42
+ raise "Already loaded repository" if @path
43
+ @path = path
44
+ end
45
+
46
+ def repository?(path)
47
+ File.exist?(File.join(path, %w{.svn}))
48
+ end
49
+
50
+ def refresh
51
+ cache.refresh
52
+ end
53
+
54
+ def cache
55
+ @cache ||= begin
56
+ c = BlockCache.new
57
+ end
58
+ end
59
+
60
+ def supported_commands
61
+ [:pull,:commit,:remote_init,:index,:switch_branch,:merge]
62
+ end
63
+
64
+ def trunk_path
65
+ if @path.include?('trunk')
66
+ trunk_path = @path[0,@path.index('trunk')] + 'trunk'
67
+ elsif @path.include?('branches')
68
+ trunk_path = @path[0,@path.index('branches')] + 'trunk'
69
+ else
70
+ trunk_path = @path + "/trunk"
71
+ end
72
+ trunk_path if repository?(trunk_path)
73
+ end
74
+
75
+ def branch_path
76
+ if trunk_path # no branches without a trunk
77
+ branch_path = trunk_path[0,trunk_path.index('trunk')] +'branches'
78
+ end
79
+ branch_path if branch_path and repository?(branch_path)
80
+ end
81
+
82
+ def branches
83
+ if trunk_path
84
+ branch_list = ['trunk']
85
+ if branch_path
86
+ Dir["#{branch_path}/*/"].map do |path|
87
+ branch_list << File.basename(path) if repository?(path)
88
+ end
89
+ end
90
+ else
91
+ branch_list = [File.basename(@path)]
92
+ end
93
+ branch_list
94
+ end
95
+
96
+ def current_branch
97
+ branch = File.basename(@path)
98
+ if trunk_path
99
+ if @path.include?(trunk_path) and repository?(trunk_path)
100
+ branch = 'trunk'
101
+ elsif @path.include?(branch_path) and repository?(branch_path)
102
+ Dir["#{branch_path}/*/"].map do |path|
103
+ branch = File.basename(path) if @path.include?(path)
104
+ end
105
+ end
106
+ end
107
+ branch
108
+ end
109
+
110
+ def switch!(branch)
111
+ unless current_branch == branch
112
+ if branch == "trunk"
113
+ new_path = trunk_path
114
+ else
115
+ new_path = "#{branch_path}/#{branch}"
116
+ end
117
+ if new_path and File.exist?(new_path)
118
+ window = Redcar.app.windows.detect {|w| w.title == File.basename(new_path)}
119
+ if window
120
+ Redcar.app.set_focussed_window(window)
121
+ else
122
+ Project::DirectoryOpenCommand.new(new_path).run
123
+ end
124
+ else
125
+ Application::Dialog.message_box("Path not found: #{new_path}.")
126
+ end
127
+ end
128
+ end
129
+
130
+ def merge!(branch)
131
+ unless current_branch == branch
132
+ if branch == "trunk"
133
+ new_path = trunk_path
134
+ else
135
+ new_path = "#{branch_path}/#{branch}"
136
+ end
137
+ if new_path and File.exist?(new_path)
138
+ client_manager.getDiffClient().doMerge(
139
+ Java::JavaIo::File.new(path), # current branch
140
+ SVNRevision::HEAD,
141
+ Java::JavaIo::File.new(new_path), # other branch
142
+ SVNRevision::HEAD,
143
+ Java::JavaIo::File.new(path), # destination
144
+ SVNDepth::INFINITY,
145
+ true, # useAncestry - if true then the paths ancestry will be noticed while calculating differences, otherwise not
146
+ false, # force - true to force the operation to run
147
+ false, # dryRun - if true then runs merge without any file changes
148
+ false # recordOnly - if true, records only the rusult of merge - mergeinfo data
149
+ )
150
+ end
151
+ end
152
+ end
153
+
154
+ def pull!(path=nil)
155
+ path = @path if not path
156
+ if repository?(@path)
157
+ client_manager.getUpdateClient().doUpdate(
158
+ Java::JavaIo::File.new(path),
159
+ SVNRevision::HEAD,
160
+ true, # allow unversioned files to exist in directory
161
+ false # store depth in directory
162
+ )
163
+ else
164
+ Application::Dialog.message_box("#{@path} is not a working copy.")
165
+ end
166
+ end
167
+
168
+ def remote_init(path,target)
169
+ client_manager.getUpdateClient().doCheckout(
170
+ SVNURL.parseURIEncoded(path),
171
+ Java::JavaIo::File.new(target),
172
+ SVNRevision::HEAD,
173
+ SVNRevision::HEAD,
174
+ SVNDepth::INFINITY,
175
+ true # allow unversioned files to exist already in directory
176
+ )
177
+ end
178
+
179
+ def index_add(change)
180
+ client_manager.getWCClient().doAdd(
181
+ Java::JavaIo::File.new(change.path), #wc item file
182
+ false, # if true, this method does not throw exceptions on already-versioned items
183
+ false, # if true, create a directory also at path
184
+ false, # not used; make use of makeParents instead
185
+ SVNDepth::INFINITY, #tree depth
186
+ false, # if true, does not apply ignore patterns to paths being added
187
+ true # if true, climb upper and schedule also all unversioned paths in the way
188
+ )
189
+ true # refresh tree
190
+ end
191
+
192
+ def index_ignore(change)
193
+ ignore_under_path(Java::JavaIo::File.new(File.dirname(change.path)).getAbsolutePath(),File.basename(change.path))
194
+ true # refresh tree
195
+ end
196
+
197
+ def index_ignore_all(extension,change)
198
+ ignore_under_path(@path,"*.#{extension}")
199
+ true
200
+ end
201
+
202
+ def ignore_under_path(path,pattern)
203
+ dir = Java::JavaIo::File.new(path)
204
+ prop = client_manager.getWCClient().doGetProperty(dir, SVNProperty::IGNORE,
205
+ SVNRevision::BASE, SVNRevision::WORKING)
206
+ if prop and not prop.getValue().toString().strip.empty?
207
+ prop = prop.getValue().toString() + "\n#{pattern}"
208
+ else
209
+ prop = pattern
210
+ end
211
+ client_manager.getWCClient().doSetProperty(dir, SVNProperty::IGNORE,
212
+ SVNPropertyValue.create(prop), false, false, nil)
213
+ end
214
+
215
+ def index_revert(change)
216
+ change_lists = Java::JavaUtil::ArrayList.new
217
+ client_manager.getWCClient().doRevert(
218
+ [Java::JavaIo::File.new(change.path)].to_java(Java::JavaIo::File),
219
+ SVNDepth::INFINITY,
220
+ change_lists # might be useful later
221
+ )
222
+ true # refresh tree
223
+ end
224
+
225
+ def index_delete(change)
226
+ if change.status[0] == :new
227
+ File.delete(change.path)
228
+ elsif change.status[0] == :indexed
229
+ index_unsave(change)
230
+ File.delete(File.new(change.path))
231
+ else
232
+ client_manager.getWCClient().doDelete(
233
+ Java::JavaIo::File.new(change.path),
234
+ false, # true to force operation to run
235
+ false, # true to delete files from filesystem
236
+ false # true to do a dry run
237
+ )
238
+ end
239
+ end
240
+
241
+ def index_save(change)
242
+ if change.status[0] == :unmerged
243
+ resolve_conflict(change)
244
+ end
245
+ end
246
+
247
+ def index_restore(change)
248
+ if change.status[0] == :missing
249
+ client_manager.getUpdateClient().doUpdate(
250
+ Java::JavaIo::File.new(change.path),
251
+ SVNRevision::HEAD,
252
+ SVNDepth::INFINITY,
253
+ true,
254
+ false
255
+ )
256
+ end
257
+ end
258
+
259
+ def index_unsave(change)
260
+ if change.status[0] == :new
261
+ # Do nothing, there's nothing to unsave
262
+ elsif change.status[0] == :indexed
263
+ index_revert(change)
264
+ else
265
+ Application::Dialog.message_box("#{change.path} is already in the repository. Use 'delete' to remove or revert to cancel local changes.")
266
+ end
267
+ end
268
+
269
+ def commit!(message,change=nil)
270
+ committer = client_manager.getCommitClient()
271
+ if change
272
+ paths = [Java::JavaIo::File.new(change.path)]
273
+ else
274
+ paths = []
275
+ indexed_changes.each { |c| paths << Java::JavaIo::File.new(c.path) }
276
+ end
277
+ packet = committer.doCollectCommitItems(
278
+ paths.to_java(Java::JavaIo::File),
279
+ true, # keep locks
280
+ false, # true to force
281
+ SVNDepth::INFINITY, # tree depth
282
+ [].to_java(:string) # changelist names array
283
+ )
284
+ idx = message.index(log_divider_message)
285
+ message = message[0,idx] if idx
286
+ committer.doCommit(packet, true, message)
287
+ true
288
+ end
289
+
290
+ def commit_message(change=nil)
291
+ msg = "\n\n#{log_divider_message}\n\n"
292
+ if change
293
+ msg << change.log_status + "\n"
294
+ else
295
+ indexed_changes.each do |c|
296
+ msg << c.log_status + "\n"
297
+ end
298
+ end
299
+ msg
300
+ end
301
+
302
+ def log_divider_message
303
+ "--This line, and those below, will be ignored--"
304
+ end
305
+
306
+ def uncommited_changes
307
+ indexed_changes + unindexed_changes
308
+ end
309
+
310
+ def unindexed_changes
311
+ populate_changes(@path,false)
312
+ end
313
+
314
+ def indexed_changes
315
+ populate_changes(@path,true)
16
316
  end
17
-
18
- # Whether to print debugging messages. Default to whatever scm is using.
317
+
318
+ def populate_changes(path,indexed)
319
+ nodes = []
320
+ find_dirs(path,indexed,nodes)
321
+ nodes.sort_by{|node| node.path}.sort_by do |node|
322
+ if File.directory?(node.path)
323
+ 0
324
+ else
325
+ 1
326
+ end
327
+ end
328
+ end
329
+
330
+ def find_dirs(path,indexed,nodes=[])
331
+ Dir["#{path.to_s}/*/"].map do |a|
332
+ #FIXME: find dirs beneath iff 'a' is not ignored
333
+ status = client_manager.getStatusClient().doStatus(
334
+ Java::JavaIo::File.new(a),false).getContentsStatus()
335
+ find_dirs(a,indexed,nodes) if versioned_statuses.include?(status)
336
+ status = check_file_status(a,indexed)
337
+ if status
338
+ diff_client = client_manager.getDiffClient()
339
+ nodes << Scm::Subversion::Change.new(a,status,[],diff_client)
340
+ end
341
+ end
342
+ check_files(path,indexed,nodes)
343
+ end
344
+
345
+ def check_files(path,indexed,nodes)
346
+ files = File.join(path.to_s, "*")
347
+ Dir.glob(files).each do |file_path|
348
+ if File.file?(file_path)
349
+ status = check_file_status(file_path,indexed)
350
+ if status
351
+ diff_client = client_manager.getDiffClient()
352
+ nodes << Scm::Subversion::Change.new(file_path,status,[],diff_client)
353
+ end
354
+ end
355
+ end
356
+ end
357
+
358
+ def check_file_status(path,indexed)
359
+ status_client = client_manager.getStatusClient()
360
+ status = status_client.doStatus(Java::JavaIo::File.new(path),false).getContentsStatus()
361
+ if indexed
362
+ s = case status
363
+ when SVNStatusType::STATUS_MODIFIED then :changed
364
+ when SVNStatusType::STATUS_MISSING then :missing
365
+ when SVNStatusType::STATUS_DELETED then :deleted
366
+ when SVNStatusType::STATUS_ADDED then :indexed
367
+ when SVNStatusType::STATUS_CONFLICTED then :unmerged
368
+ end
369
+ s
370
+ else
371
+ s = case status
372
+ when SVNStatusType::STATUS_UNVERSIONED then :new
373
+ end
374
+ s
375
+ end
376
+ end
377
+
378
+ def versioned_statuses
379
+ [
380
+ SVNStatusType::STATUS_MODIFIED,
381
+ SVNStatusType::STATUS_MISSING,
382
+ SVNStatusType::STATUS_DELETED,
383
+ SVNStatusType::STATUS_ADDED,
384
+ SVNStatusType::STATUS_CONFLICTED,
385
+ SVNStatusType::STATUS_NORMAL
386
+ ]
387
+ end
388
+
389
+ def resolve_conflict(change)
390
+ client_manager.getWCClient().doResolve(
391
+ Java::JavaIo::File.new(change.path),
392
+ SVNDepth::IMMEDIATES, # change and files beneath
393
+ true, # resolve contents conflict
394
+ true, # resolve property conflict
395
+ true, # resolve tree conflict -- man, I hate those
396
+ SVNConflictChoice.MERGED # choose file as edited and resolved
397
+ )
398
+ end
399
+
400
+ def file_diff(path)
401
+ differ = client_manager.getDiffClient()
402
+ stream = Java::JavaIo::ByteArrayOutputStream.new
403
+ file = Java::JavaIo::File.new(path)
404
+ change_lists = Java::JavaUtil::ArrayList.new
405
+ differ.doDiff(file, SVNRevision::BASE,
406
+ file, SVNRevision::WORKING,
407
+ SVNDepth::IMMEDIATES,
408
+ false,
409
+ stream,
410
+ change_lists)
411
+ stream.toString()
412
+ end
413
+
414
+ def translations
415
+ t = super
416
+ t[:index_unsave] = "Remove from commit"
417
+ t[:indexed_changes] = "Uncommitted changes"
418
+ t[:unindexed_changes] = "External files"
419
+ t[:remote_init] = "Checkout Subversion Repository"
420
+ t[:push] = "Commit changes",
421
+ t[:pull] = "Update working copy",
422
+ t[:switch_branches] = "Open branch"
423
+ t
424
+ end
425
+
19
426
  def self.debug
20
427
  Redcar::Scm::Manager.debug
21
428
  end
22
-
429
+
23
430
  def debug
24
431
  Redcar::Scm::Subversion::Manager.debug
25
432
  end
433
+
434
+ def inspect
435
+ if @path
436
+ %Q{#<Scm::Subversion::Manager "#{@path}">}
437
+ else
438
+ %Q{#<Scm::Subversion::Manager>}
439
+ end
440
+ end
26
441
  end
27
442
  end
28
443
  end
29
444
  end
30
-