svnx 1.0.1 → 2.0.6

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