svnx 1.0.1 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.glarkrc +1 -0
  4. data/Features.txt +7 -0
  5. data/Gemfile +4 -0
  6. data/History.txt +4 -0
  7. data/LICENSE +20 -0
  8. data/Manifest.txt +0 -0
  9. data/README.md +12 -0
  10. data/Rakefile +12 -0
  11. data/lib/svnx/base/action.rb +57 -52
  12. data/lib/svnx/base/cmdline.rb +58 -0
  13. data/lib/svnx/base/command.rb +49 -41
  14. data/lib/svnx/base/entries.rb +46 -45
  15. data/lib/svnx/base/entry.rb +51 -38
  16. data/lib/svnx/base/env.rb +26 -0
  17. data/lib/svnx/base/options.rb +25 -0
  18. data/lib/svnx/cat/command.rb +3 -64
  19. data/lib/svnx/cat/options.rb +28 -0
  20. data/lib/svnx/commit/command.rb +9 -0
  21. data/lib/svnx/commit/options.rb +29 -0
  22. data/lib/svnx/diff/command.rb +17 -0
  23. data/lib/svnx/diff/elements.rb +84 -0
  24. data/lib/svnx/diff/options.rb +35 -0
  25. data/lib/svnx/diff/parser.rb +105 -0
  26. data/lib/svnx/info/command.rb +4 -47
  27. data/lib/svnx/info/entries.rb +6 -8
  28. data/lib/svnx/info/entry.rb +21 -23
  29. data/lib/svnx/info/options.rb +28 -0
  30. data/lib/svnx/io/directory.rb +9 -5
  31. data/lib/svnx/io/element.rb +93 -95
  32. data/lib/svnx/log/command.rb +7 -3
  33. data/lib/svnx/log/entries.rb +17 -14
  34. data/lib/svnx/log/entry.rb +61 -49
  35. data/lib/svnx/log/options.rb +31 -0
  36. data/lib/svnx/merge/command.rb +9 -0
  37. data/lib/svnx/merge/options.rb +34 -0
  38. data/lib/svnx/project.rb +74 -0
  39. data/lib/svnx/propget/command.rb +9 -0
  40. data/lib/svnx/propget/entries.rb +15 -0
  41. data/lib/svnx/propget/entry.rb +23 -0
  42. data/lib/svnx/propget/options.rb +31 -0
  43. data/lib/svnx/propset/command.rb +9 -0
  44. data/lib/svnx/propset/options.rb +33 -0
  45. data/lib/svnx/revision/argfactory.rb +2 -2
  46. data/lib/svnx/revision/argument.rb +7 -3
  47. data/lib/svnx/revision/date.rb +27 -0
  48. data/lib/svnx/revision/error.rb +2 -2
  49. data/lib/svnx/revision/range.rb +5 -2
  50. data/lib/svnx/status/command.rb +4 -42
  51. data/lib/svnx/status/entries.rb +11 -12
  52. data/lib/svnx/status/entry.rb +43 -41
  53. data/lib/svnx/status/options.rb +28 -0
  54. data/lib/svnx/update/command.rb +9 -0
  55. data/lib/svnx/update/options.rb +25 -0
  56. data/lib/svnx/util/dateutil.rb +35 -0
  57. data/lib/svnx/util/objutil.rb +14 -0
  58. data/lib/{svnx.rb → svnx/version.rb} +2 -2
  59. data/lib/system/command/arg.rb +6 -5
  60. data/lib/system/command/cachefile.rb +29 -21
  61. data/lib/system/command/caching.rb +12 -25
  62. data/lib/system/command/line.rb +41 -30
  63. data/svnx.gemspec +34 -0
  64. metadata +85 -61
  65. data/lib/svnx/base/args.rb +0 -24
  66. data/lib/svnx/log/args.rb +0 -57
  67. data/lib/svnx/log/exec.rb +0 -27
  68. data/lib/svnx/log/line.rb +0 -42
  69. data/test/integration/info/info_test.rb +0 -21
  70. data/test/integration/log/log_test.rb +0 -74
  71. data/test/integration/status/status_test.rb +0 -35
  72. data/test/integration/svnx/io/element_test.rb +0 -235
  73. data/test/unit/svnx/base/action_test.rb +0 -49
  74. data/test/unit/svnx/cat/command_test.rb +0 -55
  75. data/test/unit/svnx/info/entries_test.rb +0 -22
  76. data/test/unit/svnx/log/args_test.rb +0 -15
  77. data/test/unit/svnx/log/entries_test.rb +0 -87
  78. data/test/unit/svnx/log/entry_test.rb +0 -15
  79. data/test/unit/svnx/log/exec_test.rb +0 -15
  80. data/test/unit/svnx/log/line_test.rb +0 -14
  81. data/test/unit/svnx/revision/argfactory_test.rb +0 -50
  82. data/test/unit/svnx/revision/argument_test.rb +0 -167
  83. data/test/unit/svnx/revision/range_test.rb +0 -48
  84. data/test/unit/svnx/status/entries_test.rb +0 -20
  85. data/test/unit/system/command/cachefile_test.rb +0 -52
  86. data/test/unit/system/command/caching_test.rb +0 -92
  87. data/test/unit/system/command/line_test.rb +0 -63
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'logue/loggable'
5
+ require 'svnx/diff/elements'
6
+
7
+ class Svnx::Diff::Parser
8
+ include Logue::Loggable
9
+
10
+ def parse_header_file lines
11
+ re = Regexp.new '^[\-\+]{3} (.*)\t\((?:nonexistent|revision (\d+))\)'
12
+ if md = re.match(lines.first)
13
+ lines.shift
14
+ Svnx::Diff::File.new filename: md[1], revision: md[2] && md[2].to_i
15
+ end
16
+ end
17
+
18
+ def parse_header_section lines
19
+ re = Regexp.new '^Index: (.*)'
20
+ if md = re.match(lines.first)
21
+ filename = md[1]
22
+ lines.shift
23
+
24
+ # discard the ==== line:
25
+ lines.shift
26
+
27
+ from = parse_header_file lines
28
+ to = parse_header_file lines
29
+
30
+ Svnx::Diff::Header.new filename: filename, from: from, to: to
31
+ end
32
+ end
33
+
34
+ def parse_ranges lines
35
+ range_re = Regexp.new '@@ \-(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@'
36
+ if md = range_re.match(lines.first)
37
+ lines.shift
38
+
39
+ from, to = [ 1, 3 ].collect do |idx|
40
+ Svnx::Diff::HunkRange.new md[idx].to_i, (md[idx + 1] || 1).to_i
41
+ end
42
+
43
+ Svnx::Diff::HunkRanges.new from, to
44
+ end
45
+ end
46
+
47
+ def parse_hunk lines
48
+ if ranges = parse_ranges(lines)
49
+ Svnx::Diff::Hunk.new(ranges, Array.new).tap do |hunk|
50
+ char_to_type = { ' ' => :context, '+' => :added, '-' => :deleted }
51
+
52
+ while !lines.empty?
53
+ if lines.first == "\"
54
+ hunk.lines << [ :context, :no_newline ]
55
+ lines.shift
56
+ elsif type = char_to_type[lines.first[0]]
57
+ hunk.lines << [ type, lines.shift[1 .. -1] ]
58
+ else
59
+ break
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def parse_hunks lines
67
+ Array.new.tap do |hunks|
68
+ while !lines.empty?
69
+ if hunk = parse_hunk(lines)
70
+ hunks << hunk
71
+ else
72
+ break
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def parse_file_diff lines
79
+ if header = parse_header_section(lines)
80
+ SvnFileDiff.new(header).tap do |diff|
81
+ if header.from && header.to
82
+ while !lines.empty?
83
+ if hunk = parse_hunk(lines)
84
+ diff.hunks << hunk
85
+ else
86
+ break
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ def parse_all_output lines
95
+ Array.new.tap do |diffs|
96
+ until lines.empty?
97
+ if filediff = parse_file_diff(lines)
98
+ diffs << filediff
99
+ else
100
+ break
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -1,53 +1,10 @@
1
1
  #!/usr/bin/ruby -w
2
2
  # -*- ruby -*-
3
3
 
4
- require 'svnx/base/command'
4
+ require 'svnx/info/options'
5
5
  require 'svnx/info/entries'
6
+ require 'svnx/base/command'
6
7
 
7
- module SVNx
8
- class InfoCommandLine < CommandLine
9
- def initialize args = Array.new
10
- super "info", args.to_a
11
- end
12
- end
13
-
14
- class InfoCommandArgs < CommandArgs
15
- attr_reader :revision
16
-
17
- def initialize args = Hash.new
18
- @revision = args[:revision]
19
- super
20
- end
21
-
22
- def to_a
23
- ary = Array.new
24
-
25
- if @revision
26
- [ @revision ].flatten.each do |rev|
27
- ary << "-r#{rev}"
28
- end
29
- end
30
-
31
- if @path
32
- ary << @path
33
- end
34
- ary
35
- end
36
- end
37
-
38
- class InfoCommand < Command
39
- def command_line
40
- InfoCommandLine.new @args
41
- end
42
- end
43
-
44
- class InfoExec
45
- attr_reader :entry
46
-
47
- def initialize args
48
- cmd = InfoCommand.new InfoCommandArgs.new(args)
49
- # info has only one entry
50
- @entry = SVNx::Info::Entries.new(:xmllines => cmd.execute)[0]
51
- end
52
- end
8
+ class Svnx::Info::Command < Svnx::Base::EntriesCommand
9
+ noncaching
53
10
  end
@@ -4,14 +4,12 @@
4
4
  require 'svnx/info/entry'
5
5
  require 'svnx/base/entries'
6
6
 
7
- module SVNx::Info
8
- class Entries < SVNx::Entries
9
- def get_elements doc
10
- doc.elements['info'].elements
11
- end
7
+ class Svnx::Info::Entries < Svnx::Base::Entries
8
+ def get_elements doc
9
+ doc.elements['info'].elements
10
+ end
12
11
 
13
- def create_entry xmlelement
14
- Entry.new :xmlelement => xmlelement
15
- end
12
+ def create_entry xmlelement
13
+ Svnx::Info::Entry.new :xmlelement => xmlelement
16
14
  end
17
15
  end
@@ -3,32 +3,30 @@
3
3
 
4
4
  require 'svnx/base/entry'
5
5
 
6
- module SVNx; module Info; end; end
6
+ module Svnx
7
+ module Info
8
+ end
9
+ end
7
10
 
8
- module SVNx::Info
9
- class Entry < SVNx::Entry
10
- attr_reader :url
11
- attr_reader :root
12
- attr_reader :kind
13
- attr_reader :path
14
- attr_reader :revision
15
- attr_reader :wc_root
11
+ class Svnx::Info::Entry < Svnx::Base::Entry
12
+ attr_reader :url
13
+ attr_reader :root
14
+ attr_reader :kind
15
+ attr_reader :path
16
+ attr_reader :revision
17
+ attr_reader :wc_root
16
18
 
17
- def set_from_element elmt
18
- set_attr_var elmt, 'kind'
19
- set_attr_var elmt, 'path'
20
- set_attr_var elmt, 'revision'
21
-
22
- set_elmt_var elmt, 'url'
23
-
24
- repo = elmt.elements['repository']
25
- set_elmt_var repo, 'root'
19
+ def set_from_element elmt
20
+ set_attr_vars elmt, 'kind', 'path', 'revision'
21
+ set_elmt_var elmt, 'url'
22
+
23
+ repo = elmt.elements['repository']
24
+ set_elmt_var repo, 'root'
26
25
 
27
- @wc_root = nil
28
- if wcinfo = elmt.elements['wc-info']
29
- if wcroot = wcinfo.elements['wcroot-abspath']
30
- @wc_root = wcroot.text
31
- end
26
+ @wc_root = nil
27
+ if wcinfo = elmt.elements['wc-info']
28
+ if wcroot = wcinfo.elements['wcroot-abspath']
29
+ @wc_root = wcroot.text
32
30
  end
33
31
  end
34
32
  end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'svnx/util/objutil'
5
+ require 'svnx/base/options'
6
+
7
+ module Svnx
8
+ module Info
9
+ end
10
+ end
11
+
12
+ class Svnx::Info::Options < Svnx::Base::Options
13
+ attr_reader :revision
14
+ attr_reader :url
15
+ attr_reader :path
16
+
17
+ def initialize args
18
+ assign args, :revision, :url, :path
19
+ end
20
+
21
+ def options_to_args
22
+ Array.new.tap do |optargs|
23
+ optargs << [ :revision, [ "-r", revision ] ]
24
+ optargs << [ :url, url ]
25
+ optargs << [ :path, path ]
26
+ end
27
+ end
28
+ end
@@ -1,10 +1,14 @@
1
1
  #!/usr/bin/ruby -w
2
2
  # -*- ruby -*-
3
3
 
4
- module SVNx::IO
5
- # An element unites an svn element and a file/directory (at least one of
6
- # which should exist).
7
-
8
- class Directory < Element
4
+ module Svnx
5
+ module IO
9
6
  end
10
7
  end
8
+
9
+
10
+ # An element unites an svn element and a file/directory (at least one of
11
+ # which should exist).
12
+
13
+ class Svnx::IO::Directory < Element
14
+ end
@@ -1,127 +1,125 @@
1
1
  #!/usr/bin/ruby -w
2
2
  # -*- ruby -*-
3
3
 
4
- require 'rubygems'
5
4
  require 'logue/loggable'
6
- require 'svnx/log/entries'
7
- require 'svnx/status/entries'
5
+ require 'svnx/log/command'
8
6
  require 'svnx/status/command'
9
- require 'svnx/info/entries'
10
7
  require 'svnx/info/command'
11
8
  require 'svnx/cat/command'
12
9
  require 'pathname'
13
10
 
14
- module SVNx; module IO; end; end
11
+ module Svnx
12
+ module IO
13
+ end
14
+ end
15
15
 
16
- module SVNx::IO
17
- # An element unites an svn element and a file/directory (at least one of
18
- # which should exist).
16
+ # An element unites an svn element and a file/directory (at least one of
17
+ # which should exist).
19
18
 
20
- class Element
21
- include Logue::Loggable, Comparable
19
+ class Svnx::IO::Element
20
+ include Logue::Loggable, Comparable
22
21
 
23
- attr_reader :svn
24
- attr_reader :path
25
- attr_reader :local
22
+ attr_reader :svn
23
+ attr_reader :path
24
+ attr_reader :local
25
+
26
+ def initialize args = Hash.new
27
+ info "args: #{args.inspect}".color("438802")
26
28
 
27
- def initialize args = Hash.new
28
- info "args: #{args.inspect}".color("438802")
29
-
30
- # svnurl = args[:svnurl]
31
- # fname = args[:filename] || args[:file] # legacy
32
- # $$$ todo: map svnurl to SVNElement, and fname to FSElement
33
-
34
- @svn = args[:svn] # || (args[:file] && SVNElement.new(:filename => args[:file]))
35
- @local = args[:local] && Pathname.new(args[:local]) # && PVN::FSElement.new(args[:local] || args[:file])
36
- @path = args[:path]
37
-
38
- info "local: #{@local.inspect}"
39
- end
29
+ # svnurl = args[:svnurl]
30
+ # fname = args[:filename] || args[:file] # legacy
31
+ # $$$ todo: map svnurl to SVNElement, and fname to FSElement
40
32
 
41
- def exist?
42
- @local && @local.exist?
43
- end
33
+ @svn = args[:svn] # || (args[:file] && SVNElement.new(:filename => args[:file]))
34
+ @local = args[:local] && Pathname.new(args[:local]) # && PVN::FSElement.new(args[:local] || args[:file])
35
+ @path = args[:path]
36
+
37
+ info "local: #{@local.inspect}"
38
+ end
44
39
 
45
- def directory?
46
- @local && @local.directory?
47
- end
40
+ def exist?
41
+ @local && @local.exist?
42
+ end
48
43
 
49
- def file?
50
- @local && @local.file?
51
- end
44
+ def directory?
45
+ @local && @local.directory?
46
+ end
52
47
 
53
- def get_info revision = nil
54
- return nil unless in_svn?
55
-
56
- usepath = @local ? @local.to_path : @path
57
- inf = SVNx::InfoExec.new path: usepath, revision: revision
58
- inf.entry
59
- end
48
+ def file?
49
+ @local && @local.file?
50
+ end
51
+
52
+ def get_info revision = nil
53
+ return nil unless in_svn?
54
+
55
+ usepath = @local ? @local.to_path : @path
56
+ inf = Svnx::Info::Command.new url: usepath, revision: revision
57
+ inf.entry
58
+ end
60
59
 
61
- def in_svn?
62
- # svn status can only be a local path:
63
- if @local
64
- st = SVNx::StatusExec.new path: @local.to_path
65
- st.entries.size == 0 || st.entries[0].status.to_s != 'unversioned'
66
- else
67
- raise "cannot determine svn status without a local path; only target '#{@path}' defined"
68
- end
60
+ def in_svn?
61
+ # svn status can only be a local path:
62
+ if @local
63
+ st = Svnx::StatusExec.new path: @local.to_path
64
+ st.entries.size == 0 || st.entries[0].status.to_s != 'unversioned'
65
+ else
66
+ raise "cannot determine svn status without a local path; only target '#{@path}' defined"
69
67
  end
68
+ end
70
69
 
71
- def find_entries args = Hash.new
72
- revision = args[:revision]
73
- status = args[:status]
74
-
75
- if revision.nil?
76
- find_by_status status
77
- else
78
- find_in_log revision, status
79
- end
70
+ def find_entries args = Hash.new
71
+ revision = args[:revision]
72
+ status = args[:status]
73
+
74
+ if revision.nil?
75
+ find_by_status status
76
+ else
77
+ find_in_log revision, status
80
78
  end
79
+ end
81
80
 
82
- def find_in_log revision, action
83
- svninfo = get_info
81
+ def find_in_log revision, action
82
+ svninfo = get_info
84
83
 
85
- filter = svninfo.url.dup
86
- filter.slice! svninfo.root
84
+ filter = svninfo.url.dup
85
+ filter.slice! svninfo.root
87
86
 
88
- # we can't cache this, because we don't know if there has been an svn
89
- # update since the previous run:
90
- logexec = SVNx::LogExec.new path: @local, revision: revision, verbose: true, use_cache: false
91
- entries = logexec.entries
92
-
93
- act = action.kind_of?(SVNx::Action) ? action : SVNx::Action.new(action)
94
- entries.match act, filter
95
- end
87
+ # we can't cache this, because we don't know if there has been an svn
88
+ # update since the previous run:
89
+ logexec = Svnx::LogExec.new path: @local, revision: revision, verbose: true, use_cache: false
90
+ entries = logexec.entries
91
+
92
+ act = action.kind_of?(Svnx::Action) ? action : Svnx::Action.new(action)
93
+ entries.match act, filter
94
+ end
96
95
 
97
- def find_by_status status
98
- statexec = SVNx::StatusExec.new path: @local, use_cache: false
99
- entries = statexec.entries
96
+ def find_by_status status
97
+ statexec = Svnx::StatusExec.new path: @local, use_cache: false
98
+ entries = statexec.entries
100
99
 
101
- entries.select do |entry|
102
- status.nil? || entry.status.to_s == status.to_s
103
- end.sort
104
- end
100
+ entries.select do |entry|
101
+ status.nil? || entry.status.to_s == status.to_s
102
+ end.sort
103
+ end
105
104
 
106
- def log_entries args = Hash.new
107
- rev = args[:revision]
108
- # use_cache should be conditional on revision:
109
- logexec = SVNx::LogExec.new :path => @local, :revision => rev && rev.to_s, :verbose => true, :use_cache => false
110
- logexec.entries
111
- end
105
+ def log_entries args = Hash.new
106
+ rev = args[:revision]
107
+ # use_cache should be conditional on revision:
108
+ logexec = Svnx::LogExec.new :path => @local, :revision => rev && rev.to_s, :verbose => true, :use_cache => false
109
+ logexec.entries
110
+ end
112
111
 
113
- def cat args = Hash.new
114
- rev = args[:revision]
115
- catexec = SVNx::CatExec.new :path => @local, :revision => rev && rev.to_s, :use_cache => false
116
- catexec.output
117
- end
112
+ def cat args = Hash.new
113
+ rev = args[:revision]
114
+ catexec = Svnx::CatExec.new :path => @local, :revision => rev && rev.to_s, :use_cache => false
115
+ catexec.output
116
+ end
118
117
 
119
- def to_s
120
- "svn => " + @svn.to_s + "; local => " + @local.to_s
121
- end
118
+ def to_s
119
+ "svn => " + @svn.to_s + "; local => " + @local.to_s
120
+ end
122
121
 
123
- def <=> other
124
- @local <=> other.local
125
- end
122
+ def <=> other
123
+ @local <=> other.local
126
124
  end
127
125
  end