svnx 2.0.6 → 2.1.0
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.
- 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
|