svnx 2.0.6 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.zshrc +2 -0
  4. data/Rakefile +2 -3
  5. data/lib/cmdline/arg.rb +12 -0
  6. data/lib/cmdline/cachefile.rb +37 -0
  7. data/lib/cmdline/caching.rb +25 -0
  8. data/lib/cmdline/filename.rb +16 -0
  9. data/lib/cmdline/gzpathname.rb +26 -0
  10. data/lib/cmdline/line.rb +57 -0
  11. data/lib/svnx/base/action.rb +31 -61
  12. data/lib/svnx/base/action_status.rb +37 -0
  13. data/lib/svnx/base/cmd.rb +20 -0
  14. data/lib/svnx/base/cmdline.rb +43 -37
  15. data/lib/svnx/base/command.rb +57 -50
  16. data/lib/svnx/base/command_factory.rb +24 -0
  17. data/lib/svnx/base/entries.rb +42 -40
  18. data/lib/svnx/base/entry.rb +46 -44
  19. data/lib/svnx/base/env.rb +14 -15
  20. data/lib/svnx/base/options.rb +22 -10
  21. data/lib/svnx/cat/command.rb +4 -2
  22. data/lib/svnx/cat/options.rb +11 -14
  23. data/lib/svnx/commit/command.rb +4 -2
  24. data/lib/svnx/commit/options.rb +11 -16
  25. data/lib/svnx/diff/command.rb +9 -7
  26. data/lib/svnx/diff/elements.rb +56 -54
  27. data/lib/svnx/diff/options.rb +14 -21
  28. data/lib/svnx/diff/parser.rb +73 -71
  29. data/lib/svnx/info/command.rb +4 -2
  30. data/lib/svnx/info/entries.rb +8 -6
  31. data/lib/svnx/info/entry.rb +23 -17
  32. data/lib/svnx/info/options.rb +11 -14
  33. data/lib/svnx/io/directory.rb +3 -1
  34. data/lib/svnx/io/element.rb +88 -86
  35. data/lib/svnx/log/command.rb +4 -2
  36. data/lib/svnx/log/entries.rb +14 -12
  37. data/lib/svnx/log/entry.rb +36 -58
  38. data/lib/svnx/log/entrypath.rb +35 -0
  39. data/lib/svnx/log/options.rb +14 -18
  40. data/lib/svnx/merge/command.rb +4 -2
  41. data/lib/svnx/merge/options.rb +17 -22
  42. data/lib/svnx/project.rb +27 -15
  43. data/lib/svnx/propget/command.rb +4 -2
  44. data/lib/svnx/propget/entries.rb +8 -6
  45. data/lib/svnx/propget/entry.rb +12 -10
  46. data/lib/svnx/propget/options.rb +13 -17
  47. data/lib/svnx/propset/command.rb +4 -2
  48. data/lib/svnx/propset/options.rb +14 -19
  49. data/lib/svnx/revision/argfactory.rb +6 -2
  50. data/lib/svnx/revision/argument.rb +22 -19
  51. data/lib/svnx/revision/date.rb +16 -16
  52. data/lib/svnx/revision/error.rb +4 -1
  53. data/lib/svnx/revision/range.rb +2 -1
  54. data/lib/svnx/status/command.rb +4 -2
  55. data/lib/svnx/status/entries.rb +13 -11
  56. data/lib/svnx/status/entry.rb +37 -39
  57. data/lib/svnx/status/options.rb +12 -15
  58. data/lib/svnx/update/command.rb +4 -2
  59. data/lib/svnx/update/options.rb +11 -12
  60. data/lib/svnx/util/classutil.rb +19 -0
  61. data/lib/svnx/util/dateutil.rb +1 -0
  62. data/lib/svnx/util/objutil.rb +36 -6
  63. data/lib/svnx/version.rb +1 -1
  64. data/repackage +1 -0
  65. data/svnx.gemspec +6 -5
  66. metadata +29 -6
  67. data/lib/system/command/arg.rb +0 -13
  68. data/lib/system/command/cachefile.rb +0 -58
  69. data/lib/system/command/caching.rb +0 -23
  70. data/lib/system/command/line.rb +0 -58
@@ -2,68 +2,75 @@
2
2
  # -*- ruby -*-
3
3
 
4
4
  require 'logue/loggable'
5
- require 'system/command/caching'
5
+ require 'cmdline/caching'
6
6
  require 'svnx/base/cmdline'
7
+ require 'svnx/util/classutil'
8
+ require 'svnx/base/command_factory'
7
9
 
8
- class Svnx::Base::Command
9
- include Logue::Loggable
10
-
11
- class << self
12
- def caching
13
- define_method :caching? do
14
- true
10
+ module Svnx::Base
11
+ class Command
12
+ include Logue::Loggable
13
+
14
+ class << self
15
+ def caching
16
+ define_method :caching? do
17
+ true
18
+ end
15
19
  end
16
- end
17
20
 
18
- def noncaching
19
- define_method :caching? do
20
- false
21
+ def noncaching
22
+ define_method :caching? do
23
+ false
24
+ end
21
25
  end
22
26
  end
23
- end
24
-
25
- attr_reader :output
26
- attr_reader :error
27
- attr_reader :status
28
-
29
- def initialize options, cls: Svnx::Base::CommandLine, exec: nil, xml: false, caching: caching?
30
- melements = module_elements
31
- modl = find_module melements
32
- opts = modl::Options.new options
33
- cmdargs = opts.to_args
34
- subcommand = melements[-1].downcase
35
-
36
- @cmdline = exec || cls.new(subcommand: subcommand, xml: xml, caching: caching, args: cmdargs)
37
-
38
- @output = @cmdline.execute
39
- @error = @cmdline.error
40
- @status = @cmdline.status
41
- end
42
27
 
43
- def module_elements
44
- mods = self.class.name.split "::"
45
- mods[0 .. -2]
46
- end
28
+ attr_reader :output
29
+ attr_reader :error
30
+ attr_reader :status
47
31
 
48
- def find_module elements = module_elements
49
- mod = elements * "::"
50
- Kernel.const_get mod
32
+ attr_reader :options
33
+
34
+ def initialize options, cls: nil, optcls: nil, exec: nil, xml: false, caching: caching?
35
+ factory = CommandFactory.new
36
+ params = factory.create self.class, cmdlinecls: cls, optcls: optcls
37
+
38
+ optcls ||= params[:options_class]
39
+
40
+ @options = optcls.new options
41
+ cmdargs = @options.to_args
42
+ subcommand = params[:subcommand]
43
+
44
+ cls ||= params[:command_line_class]
45
+
46
+ @cmdline = exec || cls.new(subcommand: subcommand, xml: xml, caching: caching, args: cmdargs)
47
+ debug "@cmdline: #{@cmdline}"
48
+
49
+ @output = @cmdline.execute
50
+ debug "@output: #{@output}"
51
+
52
+ @error = @cmdline.error
53
+ debug "@error: #{@error}"
54
+
55
+ @status = @cmdline.status
56
+ debug "@status: #{@status}"
57
+ end
51
58
  end
52
- end
53
59
 
54
- class Svnx::Base::EntriesCommand < Svnx::Base::Command
55
- attr_reader :entries
56
-
57
- def initialize options, cls: Svnx::Base::CommandLine, exec: nil, caching: caching?, xml: true, entries_class: nil
58
- super options, cls: cls, exec: exec, xml: xml, caching: caching
60
+ class EntriesCommand < Command
61
+ attr_reader :entries
59
62
 
60
- if not @output.empty?
61
- entries_class ||= begin
62
- modl = find_module
63
- modl::Entries
64
- end
63
+ def initialize options, cls: CommandLine, exec: nil, caching: caching?, xml: true, entries_class: nil
64
+ super options, cls: cls, exec: exec, xml: xml, caching: caching
65
65
 
66
- @entries = entries_class.new lines: @output
66
+ if not @output.empty?
67
+ entries_class ||= begin
68
+ modl = ClassUtil::Util.find_module self.class
69
+ modl::Entries
70
+ end
71
+
72
+ @entries = entries_class.new lines: @output
73
+ end
67
74
  end
68
75
  end
69
76
  end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'svnx/base/cmdline'
5
+ require 'svnx/util/classutil'
6
+
7
+ module Svnx::Base
8
+ class CommandFactory
9
+ include Logue::Loggable
10
+
11
+ def create cmdcls, cmdlinecls: nil, optcls: nil
12
+ melements = ClassUtil::Util.module_elements cmdcls
13
+
14
+ optcls ||= begin
15
+ modl = ClassUtil::Util.find_module cmdcls
16
+ modl::Options
17
+ end
18
+
19
+ cmdlinecls ||= CommandLine
20
+
21
+ { options_class: optcls, subcommand: melements[-1].downcase, command_line_class: cmdlinecls }
22
+ end
23
+ end
24
+ end
@@ -12,58 +12,60 @@ end
12
12
  # this is a parse/process on-demand list of entries, acting like an
13
13
  # Enumerable.
14
14
 
15
- class Svnx::Base::Entries
16
- include Logue::Loggable, Enumerable
15
+ module Svnx::Base
16
+ class Entries
17
+ include Logue::Loggable, Enumerable
17
18
 
18
- attr_reader :size
19
+ attr_reader :size
19
20
 
20
- def initialize xmllines: nil, lines: nil
21
- # it's a hash, but indexed with integers, for non-sequential access:
22
- @entries = Hash.new
21
+ def initialize xmllines: nil, lines: nil
22
+ # it's a hash, but indexed with integers, for non-sequential access:
23
+ @entries = Hash.new
23
24
 
24
- lines ||= xmllines
25
+ lines ||= xmllines
25
26
 
26
- if lines.kind_of? Array
27
- lines = lines.join ''
28
- end
29
-
30
- doc = REXML::Document.new lines
31
-
32
- @elements = get_elements doc
33
- @size = @elements.size
34
- end
27
+ if lines.kind_of? Array
28
+ lines = lines.join ''
29
+ end
35
30
 
36
- def get_elements doc
37
- raise "get_elements must be implemented for: #{self.class}"
38
- end
31
+ doc = REXML::Document.new lines
32
+
33
+ @elements = get_elements doc
34
+ @size = @elements.size
35
+ end
39
36
 
40
- def create_entry xmlelement
41
- raise "create_entry must be implemented for: #{self.class}"
42
- end
37
+ def get_elements doc
38
+ raise "get_elements must be implemented for: #{self.class}"
39
+ end
43
40
 
44
- # this doesn't handle negative indices
45
- def [] idx
46
- if entry = @entries[idx]
47
- return entry
41
+ def create_entry xmlelement
42
+ raise "create_entry must be implemented for: #{self.class}"
48
43
  end
49
- if idx < 0 || idx >= size
50
- raise "error: index #{idx} is not in range(0 .. #{size})"
44
+
45
+ # this doesn't handle negative indices
46
+ def [] idx
47
+ if entry = @entries[idx]
48
+ return entry
49
+ end
50
+ if idx < 0 || idx >= size
51
+ raise "error: index #{idx} is not in range(0 .. #{size})"
52
+ end
53
+ @entries[idx] = create_entry @elements[idx + 1]
51
54
  end
52
- @entries[idx] = create_entry @elements[idx + 1]
53
- end
54
55
 
55
- def each(&blk)
56
- # all elements must be processed before each can run:
57
- if @elements
58
- # a little confusing here: REXML does each_with_index with idx
59
- # zero-based, but elements[0] is invalid.
60
- @elements.each_with_index do |element, idx|
61
- @entries[idx] ||= create_entry(element)
56
+ def each(&blk)
57
+ # all elements must be processed before each can run:
58
+ if @elements
59
+ # a little confusing here: REXML does each_with_index with idx
60
+ # zero-based, but elements[0] is invalid.
61
+ @elements.each_with_index do |element, idx|
62
+ @entries[idx] ||= create_entry(element)
63
+ end
64
+
65
+ @elements = nil
62
66
  end
63
67
 
64
- @elements = nil
68
+ @entries.keys.sort.collect { |idx| @entries[idx] }.each(&blk)
65
69
  end
66
-
67
- @entries.keys.sort.collect { |idx| @entries[idx] }.each(&blk)
68
70
  end
69
71
  end
@@ -9,62 +9,64 @@ module Svnx
9
9
  end
10
10
  end
11
11
 
12
- class Svnx::Base::Entry
13
- include Logue::Loggable
12
+ module Svnx::Base
13
+ class Entry
14
+ include Logue::Loggable
14
15
 
15
- def initialize xmllines: nil, xmlelement: nil
16
- if xmllines
17
- if xmllines.kind_of? Array
18
- xmllines = xmllines.join ''
16
+ def initialize xmllines: nil, xmlelement: nil
17
+ if xmllines
18
+ if xmllines.kind_of? Array
19
+ xmllines = xmllines.join ''
20
+ end
21
+ doc = REXML::Document.new xmllines
22
+ set_from_xml doc
23
+ elsif xmlelement
24
+ set_from_element xmlelement
25
+ else
26
+ raise "must be initialized with xmllines (received: #{xmllines.inspect}) or xmlelement (received: #{xmlelement.inspect})"
19
27
  end
20
- doc = REXML::Document.new xmllines
21
- set_from_xml doc
22
- elsif xmlelement
23
- set_from_element xmlelement
24
- else
25
- raise "must be initialized with xmllines (received: #{xmllines.inspect}) or xmlelement (received: #{xmlelement.inspect})"
26
28
  end
27
- end
28
29
 
29
- def set_from_xml xmldoc
30
- raise "must be implemented"
31
- end
30
+ def set_from_xml xmldoc
31
+ raise "must be implemented"
32
+ end
32
33
 
33
- def set_from_element elmt
34
- raise "must be implemented"
35
- end
34
+ def set_from_element elmt
35
+ raise "must be implemented"
36
+ end
36
37
 
37
- def set_attr_var xmlelement, varname
38
- set_var varname, attribute_value(xmlelement, varname)
39
- end
38
+ def set_attr_var xmlelement, varname
39
+ set_var varname, attribute_value(xmlelement, varname)
40
+ end
40
41
 
41
- def set_attr_vars xmlelement, *varnames
42
- varnames.each do |varname|
43
- set_attr_var xmlelement, varname
42
+ def set_attr_vars xmlelement, *varnames
43
+ varnames.each do |varname|
44
+ set_attr_var xmlelement, varname
45
+ end
44
46
  end
45
- end
46
47
 
47
- def set_elmt_var xmlelement, varname
48
- set_var varname, element_text(xmlelement, varname)
49
- end
48
+ def set_elmt_var xmlelement, varname
49
+ set_var varname, element_text(xmlelement, varname)
50
+ end
50
51
 
51
- def set_elmt_vars xmlelement, *varnames
52
- varnames.each do |varname|
53
- set_elmt_var xmlelement, varname
52
+ def set_elmt_vars xmlelement, *varnames
53
+ varnames.each do |varname|
54
+ set_elmt_var xmlelement, varname
55
+ end
54
56
  end
55
- end
56
57
 
57
- def set_var varname, value
58
- instance_variable_set '@' + varname.to_s, value
59
- end
58
+ def set_var varname, value
59
+ instance_variable_set '@' + varname.to_s, value
60
+ end
60
61
 
61
- def attribute_value xmlelement, attrname
62
- xmlelement.attributes[attrname.to_s]
63
- end
62
+ def attribute_value xmlelement, attrname
63
+ xmlelement.attributes[attrname.to_s]
64
+ end
64
65
 
65
- def element_text xmlelement, elmtname
66
- elmt = xmlelement.elements[elmtname.to_s]
67
- # some elements don't have text:
68
- (elmt && elmt.text) || ""
69
- end
66
+ def element_text xmlelement, elmtname
67
+ elmt = xmlelement.elements[elmtname.to_s]
68
+ # some elements don't have text:
69
+ (elmt && elmt.text) || ""
70
+ end
71
+ end
70
72
  end
@@ -4,23 +4,22 @@
4
4
  require 'singleton'
5
5
 
6
6
  module Svnx
7
- end
8
-
9
- class Svnx::Env
10
- include Singleton
7
+ class Env
8
+ include Singleton
11
9
 
12
- # the directory into which to put cached files
13
- attr_accessor :cache_dir_name
10
+ # the directory into which to put cached files
11
+ attr_accessor :cache_dir_name
14
12
 
15
- # the environment variable, naming the cache directory
16
- attr_accessor :cache_dir_env_varname
17
-
18
- def initialize
19
- @cache_dir_name = "/tmp/svnx"
20
- @cache_dir_env_varname = "SVNX_TMP_DIR"
21
- end
13
+ # the environment variable, naming the cache directory
14
+ attr_accessor :cache_dir_env_varname
15
+
16
+ def initialize
17
+ @cache_dir_name = "/tmp/svnx"
18
+ @cache_dir_env_varname = "SVNX_TMP_DIR"
19
+ end
22
20
 
23
- def cache_dir
24
- ENV[@cache_dir_env_varname] || @cache_dir_name
21
+ def cache_dir
22
+ ENV[@cache_dir_env_varname] || @cache_dir_name
23
+ end
25
24
  end
26
25
  end
@@ -8,16 +8,28 @@ module Svnx
8
8
  end
9
9
  end
10
10
 
11
- class Svnx::Base::Options
12
- include Svnx::ObjectUtil
13
-
14
- def to_args
15
- Array.new.tap do |args|
16
- options_to_args.each do |opt|
17
- optname = opt[0]
18
- values = opt[1]
19
- if send optname
20
- args.concat [ values ].flatten
11
+ module Svnx::Base
12
+ class Options
13
+ include Svnx::ObjectUtil
14
+
15
+ def check args, valid = Array.new
16
+ invalid = args.keys.reject do |field|
17
+ valid.include? field
18
+ end
19
+
20
+ unless invalid.empty?
21
+ raise "invalid fields for #{self.class}: #{invalid.join(' ')}"
22
+ end
23
+ end
24
+
25
+ def to_args
26
+ Array.new.tap do |args|
27
+ options_to_args.each do |opt|
28
+ optname = opt[0]
29
+ values = opt[1]
30
+ if send optname
31
+ args.concat [ values ].flatten
32
+ end
21
33
  end
22
34
  end
23
35
  end
@@ -4,6 +4,8 @@
4
4
  require 'svnx/cat/options'
5
5
  require 'svnx/base/command'
6
6
 
7
- class Svnx::Cat::Command < Svnx::Base::Command
8
- caching
7
+ module Svnx::Cat
8
+ class Command < Svnx::Base::Command
9
+ caching
10
+ end
9
11
  end