buzzware-buzzcore 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +23 -0
- data/README.rdoc +46 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/buzzcore.gemspec +77 -0
- data/buzzcore.vpj +93 -0
- data/buzzcore.vpw +6 -0
- data/lib/buzzcore.rb +2 -0
- data/lib/buzzcore/cap_utils.rb +181 -0
- data/lib/buzzcore/config.rb +210 -0
- data/lib/buzzcore/database_utils.rb +86 -0
- data/lib/buzzcore/enum.rb +50 -0
- data/lib/buzzcore/extend_base_classes.rb +320 -0
- data/lib/buzzcore/ftp_extra.rb +188 -0
- data/lib/buzzcore/logging.rb +159 -0
- data/lib/buzzcore/misc_utils.rb +382 -0
- data/lib/buzzcore/require_paths.rb +28 -0
- data/lib/buzzcore/shell_extras.rb +80 -0
- data/lib/buzzcore/string_utils.rb +53 -0
- data/lib/buzzcore/text_doc.rb +70 -0
- data/lib/buzzcore/thread_utils.rb +709 -0
- data/lib/buzzcore/xml_utils.rb +184 -0
- data/test/buzzcore_test.rb +7 -0
- data/test/config_test.rb +201 -0
- data/test/credentials_test.rb +71 -0
- data/test/shell_test.rb +54 -0
- data/test/test_helper.rb +10 -0
- metadata +95 -0
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'rexml/xpath'
|
4
|
+
require 'buzzcore/misc_utils'
|
5
|
+
|
6
|
+
module XmlUtils
|
7
|
+
|
8
|
+
BASIC_HEADER = '<?xml version="1.0"?>'
|
9
|
+
|
10
|
+
def self.get_url_root(url)
|
11
|
+
xml = Net::HTTP.get(URI(url))
|
12
|
+
return nil if !xml
|
13
|
+
xdoc = REXML::Document.new(xml)
|
14
|
+
return nil if !xdoc
|
15
|
+
root = xdoc.root
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_xml_root(xml)
|
19
|
+
xdoc = REXML::Document.new(xml)
|
20
|
+
return nil if !xdoc
|
21
|
+
root = xdoc.root
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.get_file_root(aFilename)
|
25
|
+
return nil unless File.exists?(aFilename)
|
26
|
+
get_xml_root(MiscUtils.string_from_file(aFilename))
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.single_node(node,xpath,default=nil)
|
30
|
+
return default if node.nil? || xpath.nil? || xpath==''
|
31
|
+
val = REXML::XPath.first(node,xpath)
|
32
|
+
return val.nil? ? default : val
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.peek_node(node,xpath,default=nil)
|
36
|
+
return default if node.nil? || xpath.nil? || xpath==''
|
37
|
+
val = REXML::XPath.first(node,xpath)
|
38
|
+
return val.nil? ? default : val.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.peek_node_value(aNode,aXPath,aDefault=nil)
|
42
|
+
node = single_node(aNode,aXPath)
|
43
|
+
return node.to_s if node.is_a?(REXML::Attribute)
|
44
|
+
return node.nil? ? aDefault : node.text()
|
45
|
+
end
|
46
|
+
|
47
|
+
# convert <root><a>one</a><b>two</b></root> to {'a' => 'one', 'b' => 'two'}
|
48
|
+
def self.hash_from_elements(aXMLRoot)
|
49
|
+
result = {}
|
50
|
+
aXMLRoot.elements.each{|e| result[e.name] = e.text}
|
51
|
+
return result
|
52
|
+
end
|
53
|
+
|
54
|
+
# given '<tag a="1" b="2">textblah</tag>' returns {:name=>"tag", :text=>"textblah", "a"=>"1", "b"=>"2"}
|
55
|
+
def self.hash_from_tag(aTagString)
|
56
|
+
result = {}
|
57
|
+
tag = get_xml_root(aTagString)
|
58
|
+
return nil if !tag
|
59
|
+
tag.attributes.each_attribute {|attr| result[attr.expanded_name] = attr.value }
|
60
|
+
result[:name] = tag.name
|
61
|
+
result[:text] = tag.text if tag.text
|
62
|
+
return result
|
63
|
+
end
|
64
|
+
|
65
|
+
# given {:name=>"tag", :text=>"textblah", "a"=>"1", "b"=>"2"} returns '<tag a="1" b="2">textblah</tag>'
|
66
|
+
def self.tag_from_hash(aHash,aName=nil,aText=nil)
|
67
|
+
aName ||= aHash[:name]
|
68
|
+
aText ||= aHash[:text]
|
69
|
+
result = "<#{aName}"
|
70
|
+
aHash.each {|k,v| result += " #{k}=\"#{encode(v.to_s)}\"" if k.is_a? String}
|
71
|
+
result += aText ? " >#{aText}</#{aName}>" : " />"
|
72
|
+
end
|
73
|
+
|
74
|
+
# returns first node added
|
75
|
+
def self.add_xml_from_string(aString,aNode)
|
76
|
+
return nil unless xdoc = REXML::Document.new('<?xml version="1.0" encoding="UTF-8"?><root>'+aString+'</root>')
|
77
|
+
result = nil
|
78
|
+
r = xdoc.root
|
79
|
+
while r.has_elements? do
|
80
|
+
e = r.delete_element(1)
|
81
|
+
result = e unless result
|
82
|
+
e.parent = nil
|
83
|
+
aNode.add_element(e)
|
84
|
+
end
|
85
|
+
return result
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.hash_to_xml(aHash,aRootName,aDocHeader=true)
|
89
|
+
xdoc = REXML::Document.new(BASIC_HEADER)
|
90
|
+
root = xdoc.add_element(aRootName)
|
91
|
+
aHash.each do |n,v|
|
92
|
+
root.add_element(n).add_text(v)
|
93
|
+
end
|
94
|
+
return xdoc
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.read_simple_items(aRoot,aParentXPath=nil)
|
98
|
+
result = {}
|
99
|
+
xp = aParentXPath ? File.join(aParentXPath,'Item') : 'Item'
|
100
|
+
REXML::XPath.each(aRoot, xp) do |item|
|
101
|
+
result[item.attribute('Name').to_s] = item.text
|
102
|
+
end
|
103
|
+
return result
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.quick_write_simple_items(aHash,aParent)
|
107
|
+
return "<#{aParent} />\n" if !aHash || aHash.empty?
|
108
|
+
result = "<#{aParent}>\n"
|
109
|
+
aHash.each {|key,value| result += "\t<Item Name=\"#{key.to_s}\">#{value.to_s}</Item>\n" }
|
110
|
+
result += "<#{aParent}/>\n"
|
111
|
+
return result
|
112
|
+
end
|
113
|
+
|
114
|
+
# reads the simple items format given either a filename or xml node
|
115
|
+
def self.read_config_values(aXmlConfig)
|
116
|
+
xmlRoot = aXmlConfig.is_a?(REXML::Element) ? aXmlConfig : get_file_root(aXmlConfig)
|
117
|
+
return read_simple_items(xmlRoot,'/Config/SimpleItems')
|
118
|
+
end
|
119
|
+
|
120
|
+
# Takes a node or xml string and writes it out formatted nicely.
|
121
|
+
# aOutput may be given eg. a stream or nil can be given to get a returned string
|
122
|
+
def self.format_nicely(aXml,aOutput=nil)
|
123
|
+
aXml = REXML::Document.new(aXml) unless aXml.is_a?(REXML::Element)
|
124
|
+
f = REXML::Formatters::Pretty.new(2,true)
|
125
|
+
f.compact = true
|
126
|
+
f.width = 120
|
127
|
+
aOutput ||= ''
|
128
|
+
f.write(aXml,aOutput)
|
129
|
+
return aOutput
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.encode(aString)
|
133
|
+
result = aString.clone;
|
134
|
+
result.gsub!('&','&')
|
135
|
+
result.gsub!('<','<')
|
136
|
+
result.gsub!('>','>')
|
137
|
+
result.gsub!('"','"')
|
138
|
+
result.gsub!("'",''')
|
139
|
+
result.gsub!(/[\x80-\xFF]/) {|c| "&#x#{'%X' % c[0]};"}
|
140
|
+
return result
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.hash_to_deflist(aHash,aBuilder=nil)
|
144
|
+
aBuilder ||= Builder::XmlMarkup.new(:indent => 2)
|
145
|
+
aBuilder.dl do
|
146
|
+
aHash.each do |k,v|
|
147
|
+
aBuilder.dt(k.to_s)
|
148
|
+
aBuilder.dd(v.to_s)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.data_to_table(aRowHashes,aCaption=nil,aColNames=nil,aBuilder=nil)
|
154
|
+
aBuilder ||= Builder::XmlMarkup.new(:indent => 2)
|
155
|
+
aBuilder.table do
|
156
|
+
if aCaption.is_a? String
|
157
|
+
aBuilder.caption(aCaption)
|
158
|
+
elsif aCaption.is_a? Hash
|
159
|
+
aBuilder.caption do
|
160
|
+
XmlUtils.hash_to_deflist(aCaption,aBuilder)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
aColNames ||= aRowHashes.first.keys
|
164
|
+
aBuilder.thead do
|
165
|
+
aBuilder.tr do
|
166
|
+
aColNames.each do |name|
|
167
|
+
aBuilder.td(name.to_s)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
aBuilder.tbody do
|
172
|
+
aRowHashes.each do |row|
|
173
|
+
aBuilder.tr do
|
174
|
+
aColNames.each do |name|
|
175
|
+
aBuilder.td(row[name].to_s)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'buzzcore/misc_utils'
|
3
|
+
require 'buzzcore/config'
|
4
|
+
require 'buzzcore/shell_extras'
|
5
|
+
require 'test/unit'
|
6
|
+
gem 'Shoulda'; require 'shoulda'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
class ConfigTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
#def setup
|
12
|
+
# @temp_dir = MiscUtils.make_temp_dir('CredentialsTest')
|
13
|
+
# @user_dir = File.join(@temp_dir,'home/fred')
|
14
|
+
# FileUtils.mkdir_p(@user_dir)
|
15
|
+
# @project_dir = File.join(@temp_dir,'projects/moon')
|
16
|
+
# @current_dir = File.join(@project_dir,'source')
|
17
|
+
# FileUtils.mkdir_p(@current_dir)
|
18
|
+
# ::Credentials.const_set('HOME_PATH',@user_dir)
|
19
|
+
#end
|
20
|
+
|
21
|
+
def config_xml
|
22
|
+
return XmlUtils.get_xml_root('<?xml version="1.0" encoding="UTF-8"?><Config></Config>')
|
23
|
+
end
|
24
|
+
|
25
|
+
should "read values of same type as default value classes" do
|
26
|
+
xml = config_xml
|
27
|
+
# values given of native type
|
28
|
+
defaults = {
|
29
|
+
:a => String,
|
30
|
+
:b => Fixnum,
|
31
|
+
:c => Float,
|
32
|
+
:d => TrueClass,
|
33
|
+
:e => FalseClass,
|
34
|
+
}
|
35
|
+
values = {
|
36
|
+
:a => '1',
|
37
|
+
:b => 3,
|
38
|
+
:c => 2.3,
|
39
|
+
:d => true,
|
40
|
+
:e => false,
|
41
|
+
}
|
42
|
+
config = ConfigClass.new(defaults)
|
43
|
+
config.read(values)
|
44
|
+
puts config.inspect
|
45
|
+
assert_equal config[:a],'1'
|
46
|
+
assert_equal config[:b],3
|
47
|
+
assert_equal config[:c],2.3
|
48
|
+
assert_equal config[:d],true
|
49
|
+
assert_equal config[:e],false
|
50
|
+
end
|
51
|
+
|
52
|
+
should "read values of different type as default value classes" do
|
53
|
+
xml = config_xml
|
54
|
+
# values given of native type
|
55
|
+
defaults = {
|
56
|
+
:a => String,
|
57
|
+
:b => Fixnum,
|
58
|
+
:c => Float,
|
59
|
+
:d => TrueClass,
|
60
|
+
:e => FalseClass,
|
61
|
+
}
|
62
|
+
values = {
|
63
|
+
:a => 1,
|
64
|
+
:b => 3.2,
|
65
|
+
:c => 2,
|
66
|
+
:d => 'false',
|
67
|
+
:e => 0,
|
68
|
+
}
|
69
|
+
config = ConfigClass.new(defaults)
|
70
|
+
config.read(values)
|
71
|
+
assert_equal config[:a],'1'
|
72
|
+
assert_equal config[:b],3
|
73
|
+
assert_equal config[:c],2.0
|
74
|
+
assert_equal config[:d],false
|
75
|
+
assert_equal config[:e],false
|
76
|
+
end
|
77
|
+
|
78
|
+
should "read values when defaults are actual values, and values of correct type" do
|
79
|
+
xml = config_xml
|
80
|
+
# values given of native type
|
81
|
+
defaults = {
|
82
|
+
:a => 'X',
|
83
|
+
:b => 6,
|
84
|
+
:c => 7.8,
|
85
|
+
:d => true,
|
86
|
+
:e => false,
|
87
|
+
}
|
88
|
+
values = {
|
89
|
+
:a => 'why',
|
90
|
+
:b => 3,
|
91
|
+
:c => 2.9,
|
92
|
+
:d => false,
|
93
|
+
:e => true,
|
94
|
+
}
|
95
|
+
config = ConfigClass.new(defaults)
|
96
|
+
config.read(values)
|
97
|
+
assert_equal config[:a],'why'
|
98
|
+
assert_equal config[:b],3
|
99
|
+
assert_equal config[:c],2.9
|
100
|
+
assert_equal config[:d],false
|
101
|
+
assert_equal config[:e],true
|
102
|
+
end
|
103
|
+
|
104
|
+
should "read values when defaults are actual values, and values of other type" do
|
105
|
+
xml = config_xml
|
106
|
+
# values given of native type
|
107
|
+
defaults = {
|
108
|
+
:a => 'X',
|
109
|
+
:b => 6,
|
110
|
+
:c => 7.8,
|
111
|
+
:d => true,
|
112
|
+
:e => false,
|
113
|
+
}
|
114
|
+
values = {
|
115
|
+
:a => 123.4,
|
116
|
+
:b => '7',
|
117
|
+
:c => '9',
|
118
|
+
:d => 0,
|
119
|
+
:e => 'yes',
|
120
|
+
}
|
121
|
+
config = ConfigClass.new(defaults)
|
122
|
+
config.read(values)
|
123
|
+
assert_equal config[:a],'123.4'
|
124
|
+
assert_equal config[:b],7
|
125
|
+
assert_equal config[:c],9.0
|
126
|
+
assert_equal config[:d],false
|
127
|
+
assert_equal config[:e],true
|
128
|
+
end
|
129
|
+
|
130
|
+
should "let value defaults through, exclude values not in defaults" do
|
131
|
+
xml = config_xml
|
132
|
+
# values given of native type
|
133
|
+
defaults = {
|
134
|
+
:a => 'X',
|
135
|
+
:b => 6,
|
136
|
+
:c => 7.8,
|
137
|
+
:d => true,
|
138
|
+
:e => false,
|
139
|
+
}
|
140
|
+
values = {
|
141
|
+
:x => 89
|
142
|
+
}
|
143
|
+
config = ConfigClass.new(defaults)
|
144
|
+
config.read(values)
|
145
|
+
assert_equal config[:a],'X'
|
146
|
+
assert_equal config[:b],6
|
147
|
+
assert_equal config[:c],7.8
|
148
|
+
assert_equal config[:d],true
|
149
|
+
assert_equal config[:e],false
|
150
|
+
assert_equal config[:x],nil
|
151
|
+
end
|
152
|
+
|
153
|
+
should "let value defaults through, exclude values not in defaults" do
|
154
|
+
xml = config_xml
|
155
|
+
# values given of native type
|
156
|
+
defaults = {
|
157
|
+
:a => 'X',
|
158
|
+
:b => 6,
|
159
|
+
:c => 7.8,
|
160
|
+
:d => true,
|
161
|
+
:e => false,
|
162
|
+
}
|
163
|
+
values = {
|
164
|
+
:x => 89
|
165
|
+
}
|
166
|
+
config = ConfigClass.new(defaults)
|
167
|
+
config.read(values)
|
168
|
+
assert_equal config[:a],'X'
|
169
|
+
assert_equal config[:b],6
|
170
|
+
assert_equal config[:c],7.8
|
171
|
+
assert_equal config[:d],true
|
172
|
+
assert_equal config[:e],false
|
173
|
+
assert_equal config[:x],nil
|
174
|
+
end
|
175
|
+
|
176
|
+
should "let Class defaults through, exclude values not in defaults" do
|
177
|
+
xml = config_xml
|
178
|
+
# values given of native type
|
179
|
+
defaults = {
|
180
|
+
:a => String,
|
181
|
+
:b => Fixnum,
|
182
|
+
:c => Float,
|
183
|
+
:d => TrueClass,
|
184
|
+
:e => FalseClass,
|
185
|
+
}
|
186
|
+
values = {
|
187
|
+
'x' => 89,
|
188
|
+
:a => 89
|
189
|
+
}
|
190
|
+
config = ConfigClass.new(defaults)
|
191
|
+
config.read(values)
|
192
|
+
assert_equal config[:a],'89'
|
193
|
+
assert_equal config[:b],nil
|
194
|
+
assert_equal config[:c],nil
|
195
|
+
assert_equal config[:d],nil
|
196
|
+
assert_equal config[:e],nil
|
197
|
+
assert_equal config[:x],nil
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'buzzcore/misc_utils'
|
3
|
+
require 'buzzcore/config'
|
4
|
+
require 'buzzcore/shell_extras'
|
5
|
+
require 'test/unit'
|
6
|
+
gem 'Shoulda'; require 'shoulda'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
class CredentialsTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@temp_dir = MiscUtils.make_temp_dir('CredentialsTest')
|
13
|
+
@user_dir = File.join(@temp_dir,'home/fred')
|
14
|
+
FileUtils.mkdir_p(@user_dir)
|
15
|
+
@project_dir = File.join(@temp_dir,'projects/moon')
|
16
|
+
@current_dir = File.join(@project_dir,'source')
|
17
|
+
FileUtils.mkdir_p(@current_dir)
|
18
|
+
::Credentials.const_set('HOME_PATH',@user_dir)
|
19
|
+
end
|
20
|
+
|
21
|
+
def cred_xml
|
22
|
+
return XmlUtils.get_xml_root('<?xml version="1.0" encoding="UTF-8"?><Credentials></Credentials>')
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_namespace_xml(aCredentialsXml,aNamespace,aItems=nil)
|
26
|
+
result = XmlUtils.add_xml_from_string("<SimpleItems Namespace=\"#{aNamespace.to_s}\"></SimpleItems>",aCredentialsXml)
|
27
|
+
return result unless aItems
|
28
|
+
aItems.each do |n,v|
|
29
|
+
XmlUtils.add_xml_from_string("<Item Name=\"#{n.to_s}\">#{v.to_s}</Item>",result)
|
30
|
+
end
|
31
|
+
return result
|
32
|
+
end
|
33
|
+
|
34
|
+
should "read SimpleItems" do
|
35
|
+
xml = XmlUtils.get_xml_root('<?xml version="1.0"?><Credentials><SimpleItems Namespace="global"><Item Name="a">5</Item><Item Name="b">hello</Item></SimpleItems></Credentials>')
|
36
|
+
si = REXML::XPath.first(xml,'/Credentials/SimpleItems')
|
37
|
+
values = XmlUtils.read_simple_items(si)
|
38
|
+
assert_equal values['a'],'5'
|
39
|
+
assert_equal values['b'],'hello'
|
40
|
+
end
|
41
|
+
|
42
|
+
should "load local credentials file" do
|
43
|
+
xml = cred_xml()
|
44
|
+
add_namespace_xml(xml.root,:global,{:a=>5,'b'=>'hello'})
|
45
|
+
MiscUtils.string_to_file(xml.document.to_s,File.join(@project_dir,Credentials::CRED_FILENAME))
|
46
|
+
cred = Credentials.new(:moon,@current_dir)
|
47
|
+
assert_equal cred[:a],'5'
|
48
|
+
assert_equal cred[:b],'hello'
|
49
|
+
end
|
50
|
+
|
51
|
+
should "load user credentials file" do
|
52
|
+
xml = cred_xml()
|
53
|
+
add_namespace_xml(xml,:global,{:a=>7,'b'=>'apples'})
|
54
|
+
MiscUtils.string_to_file(xml.document.to_s,File.join(@user_dir,Credentials::CRED_FILENAME))
|
55
|
+
cred = Credentials.new(:moon,@current_dir)
|
56
|
+
assert_equal cred[:a],'7'
|
57
|
+
assert_equal cred[:b],'apples'
|
58
|
+
end
|
59
|
+
|
60
|
+
should "specified namespace values should override global, and other namespace doesn't interfere" do
|
61
|
+
xml = cred_xml()
|
62
|
+
add_namespace_xml(xml,:global,{:a=>1,'b'=>'green'})
|
63
|
+
add_namespace_xml(xml,:moon,{'b'=>'red'})
|
64
|
+
add_namespace_xml(xml,:blah,{'a'=>'yellow','b'=>20})
|
65
|
+
MiscUtils.string_to_file(xml.document.to_s,File.join(@user_dir,Credentials::CRED_FILENAME))
|
66
|
+
cred = Credentials.new(:moon,@current_dir)
|
67
|
+
assert_equal cred[:a],'1'
|
68
|
+
assert_equal cred[:b],'red'
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|