svnx 2.0.6 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.zshrc +2 -0
- data/Rakefile +2 -3
- data/lib/cmdline/arg.rb +12 -0
- data/lib/cmdline/cachefile.rb +37 -0
- data/lib/cmdline/caching.rb +25 -0
- data/lib/cmdline/filename.rb +16 -0
- data/lib/cmdline/gzpathname.rb +26 -0
- data/lib/cmdline/line.rb +57 -0
- data/lib/svnx/base/action.rb +31 -61
- data/lib/svnx/base/action_status.rb +37 -0
- data/lib/svnx/base/cmd.rb +20 -0
- data/lib/svnx/base/cmdline.rb +43 -37
- data/lib/svnx/base/command.rb +57 -50
- data/lib/svnx/base/command_factory.rb +24 -0
- data/lib/svnx/base/entries.rb +42 -40
- data/lib/svnx/base/entry.rb +46 -44
- data/lib/svnx/base/env.rb +14 -15
- data/lib/svnx/base/options.rb +22 -10
- data/lib/svnx/cat/command.rb +4 -2
- data/lib/svnx/cat/options.rb +11 -14
- data/lib/svnx/commit/command.rb +4 -2
- data/lib/svnx/commit/options.rb +11 -16
- data/lib/svnx/diff/command.rb +9 -7
- data/lib/svnx/diff/elements.rb +56 -54
- data/lib/svnx/diff/options.rb +14 -21
- data/lib/svnx/diff/parser.rb +73 -71
- data/lib/svnx/info/command.rb +4 -2
- data/lib/svnx/info/entries.rb +8 -6
- data/lib/svnx/info/entry.rb +23 -17
- data/lib/svnx/info/options.rb +11 -14
- data/lib/svnx/io/directory.rb +3 -1
- data/lib/svnx/io/element.rb +88 -86
- data/lib/svnx/log/command.rb +4 -2
- data/lib/svnx/log/entries.rb +14 -12
- data/lib/svnx/log/entry.rb +36 -58
- data/lib/svnx/log/entrypath.rb +35 -0
- data/lib/svnx/log/options.rb +14 -18
- data/lib/svnx/merge/command.rb +4 -2
- data/lib/svnx/merge/options.rb +17 -22
- data/lib/svnx/project.rb +27 -15
- data/lib/svnx/propget/command.rb +4 -2
- data/lib/svnx/propget/entries.rb +8 -6
- data/lib/svnx/propget/entry.rb +12 -10
- data/lib/svnx/propget/options.rb +13 -17
- data/lib/svnx/propset/command.rb +4 -2
- data/lib/svnx/propset/options.rb +14 -19
- data/lib/svnx/revision/argfactory.rb +6 -2
- data/lib/svnx/revision/argument.rb +22 -19
- data/lib/svnx/revision/date.rb +16 -16
- data/lib/svnx/revision/error.rb +4 -1
- data/lib/svnx/revision/range.rb +2 -1
- data/lib/svnx/status/command.rb +4 -2
- data/lib/svnx/status/entries.rb +13 -11
- data/lib/svnx/status/entry.rb +37 -39
- data/lib/svnx/status/options.rb +12 -15
- data/lib/svnx/update/command.rb +4 -2
- data/lib/svnx/update/options.rb +11 -12
- data/lib/svnx/util/classutil.rb +19 -0
- data/lib/svnx/util/dateutil.rb +1 -0
- data/lib/svnx/util/objutil.rb +36 -6
- data/lib/svnx/version.rb +1 -1
- data/repackage +1 -0
- data/svnx.gemspec +6 -5
- metadata +29 -6
- data/lib/system/command/arg.rb +0 -13
- data/lib/system/command/cachefile.rb +0 -58
- data/lib/system/command/caching.rb +0 -23
- data/lib/system/command/line.rb +0 -58
data/lib/svnx/base/command.rb
CHANGED
@@ -2,68 +2,75 @@
|
|
2
2
|
# -*- ruby -*-
|
3
3
|
|
4
4
|
require 'logue/loggable'
|
5
|
-
require '
|
5
|
+
require 'cmdline/caching'
|
6
6
|
require 'svnx/base/cmdline'
|
7
|
+
require 'svnx/util/classutil'
|
8
|
+
require 'svnx/base/command_factory'
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
28
|
+
attr_reader :output
|
29
|
+
attr_reader :error
|
30
|
+
attr_reader :status
|
47
31
|
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
55
|
-
|
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
|
-
|
61
|
-
|
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
|
-
|
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
|
data/lib/svnx/base/entries.rb
CHANGED
@@ -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
|
-
|
16
|
-
|
15
|
+
module Svnx::Base
|
16
|
+
class Entries
|
17
|
+
include Logue::Loggable, Enumerable
|
17
18
|
|
18
|
-
|
19
|
+
attr_reader :size
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
+
lines ||= xmllines
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
31
|
+
doc = REXML::Document.new lines
|
32
|
+
|
33
|
+
@elements = get_elements doc
|
34
|
+
@size = @elements.size
|
35
|
+
end
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
def get_elements doc
|
38
|
+
raise "get_elements must be implemented for: #{self.class}"
|
39
|
+
end
|
43
40
|
|
44
|
-
|
45
|
-
|
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
|
-
|
50
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
@
|
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
|
data/lib/svnx/base/entry.rb
CHANGED
@@ -9,62 +9,64 @@ module Svnx
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
module Svnx::Base
|
13
|
+
class Entry
|
14
|
+
include Logue::Loggable
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
30
|
+
def set_from_xml xmldoc
|
31
|
+
raise "must be implemented"
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
def set_from_element elmt
|
35
|
+
raise "must be implemented"
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
def set_attr_var xmlelement, varname
|
39
|
+
set_var varname, attribute_value(xmlelement, varname)
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
48
|
+
def set_elmt_var xmlelement, varname
|
49
|
+
set_var varname, element_text(xmlelement, varname)
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
58
|
-
|
59
|
-
|
58
|
+
def set_var varname, value
|
59
|
+
instance_variable_set '@' + varname.to_s, value
|
60
|
+
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
def attribute_value xmlelement, attrname
|
63
|
+
xmlelement.attributes[attrname.to_s]
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
data/lib/svnx/base/env.rb
CHANGED
@@ -4,23 +4,22 @@
|
|
4
4
|
require 'singleton'
|
5
5
|
|
6
6
|
module Svnx
|
7
|
-
|
8
|
-
|
9
|
-
class Svnx::Env
|
10
|
-
include Singleton
|
7
|
+
class Env
|
8
|
+
include Singleton
|
11
9
|
|
12
|
-
|
13
|
-
|
10
|
+
# the directory into which to put cached files
|
11
|
+
attr_accessor :cache_dir_name
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
24
|
-
|
21
|
+
def cache_dir
|
22
|
+
ENV[@cache_dir_env_varname] || @cache_dir_name
|
23
|
+
end
|
25
24
|
end
|
26
25
|
end
|
data/lib/svnx/base/options.rb
CHANGED
@@ -8,16 +8,28 @@ module Svnx
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
Array.new
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|