android-xml 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +127 -0
- data/lib/android-xml.rb +6 -0
- data/lib/android-xml/defaults.rb +44 -0
- data/lib/android-xml/file.rb +42 -0
- data/lib/android-xml/main.rb +115 -0
- data/lib/android-xml/tag.rb +132 -0
- data/lib/android-xml/version.rb +3 -0
- data/spec/android_manifest_spec.rb +55 -0
- data/spec/android_menu_spec.rb +70 -0
- data/spec/android_resources_spec.rb +68 -0
- data/spec/generate_spec.rb +124 -0
- metadata +76 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 86309a38baac267caea7eea59fde2d5b2212b118
|
4
|
+
data.tar.gz: ac749e5475b16b96a535fa907dbe15b133bda2ea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a8753e1c48772ebdc4f521c42e4d482a6027e9c51303029d5c5e091a6ce75e6f3417e5f3a84046e8303ce43d6bac2c9e1e8bbb86ae048456e57bbae4354800a4
|
7
|
+
data.tar.gz: 291e6376163cce849152830086d4e975630c2dc1b600f7e64288c3818a476f39a14add0663dfcde58f684da07fcb9711644ba3d4a9f2bc02295ecd642aa5640a
|
data/README.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
AndroidXml
|
2
|
+
---------
|
3
|
+
|
4
|
+
gem install android-xml
|
5
|
+
|
6
|
+
# Quick start
|
7
|
+
|
8
|
+
###### generate_xml.rb
|
9
|
+
```ruby
|
10
|
+
require 'android-xml'
|
11
|
+
|
12
|
+
AndroidXml.file('res/values/strings.xml') do
|
13
|
+
resource do
|
14
|
+
string(name: 'app_name') { 'AppityApp' }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
AndroidXml.write_all
|
19
|
+
```
|
20
|
+
|
21
|
+
> ruby generate_xml.rb
|
22
|
+
✓ res/values/strings.xml
|
23
|
+
|
24
|
+
> cat res/values/strings.xml
|
25
|
+
<?xml version="1.0" encoding="utf-8"?>
|
26
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
27
|
+
<resources>
|
28
|
+
<string name="app_name">AppityApp</string>
|
29
|
+
</resources>
|
30
|
+
|
31
|
+
# About
|
32
|
+
|
33
|
+
With **AndroidXml** you can generate an XML file with much less fuss. It will
|
34
|
+
take care of prefixing attributes with `android:` when required, it includes the
|
35
|
+
`<?xml ?>` tag, includes the `xmlns:` attribute on your root node (but only when
|
36
|
+
required)... all that good stuff!
|
37
|
+
|
38
|
+
You still need to understand the format that the various Android XML files
|
39
|
+
expect, but hopefully you get a good productivity boost.
|
40
|
+
|
41
|
+
# More examples
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
# The dreaded AndroidManifest file!
|
45
|
+
AndroidXml.file('AndroidManifest.xml') do
|
46
|
+
manifest package: 'com.your_name_here.AppityApp', versionCode: 1, versionName: 1.0 do
|
47
|
+
uses_sdk minSdkVersion: 11
|
48
|
+
|
49
|
+
application label: '@string/app_name', icon: '@drawable/ic_launcher' do
|
50
|
+
activity name: 'MainActivity', label: '@string/app_name' do
|
51
|
+
intent_filter do
|
52
|
+
# these helpers are defined in `android-xml/defaults.rb`,
|
53
|
+
# and you can easily add your own with an AndroidXml.setup block (see
|
54
|
+
# below)
|
55
|
+
main_action
|
56
|
+
launcher_category
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
activity name: 'DisplayMessageActivity',
|
61
|
+
label: '@string/app_name',
|
62
|
+
parentActivityName: 'com.your_name_here.AppityApp.MainActivity'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# You can generate multiple files from one .rb file
|
68
|
+
AndroidXml.file('res/values-jp/strings.xml') do
|
69
|
+
resource do
|
70
|
+
string(name: 'app_name') { 'アッピティアップ' }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
AndroidXml.write_all
|
75
|
+
```
|
76
|
+
|
77
|
+
# Helpers
|
78
|
+
|
79
|
+
Here's how we create the main_action helper, or if you need to specify that some
|
80
|
+
attributes don't need the `android:` prefix.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
AndroidXml.setup do
|
84
|
+
# the hash syntax specifies the `shortcut => actual-tag-name`
|
85
|
+
tag :main_action => 'action' do
|
86
|
+
# then we can assign default attributes
|
87
|
+
defaults name: 'android.intent.action.MAIN'
|
88
|
+
end
|
89
|
+
tag :style do
|
90
|
+
# <style name="..."> is correct - NOT <style android:name="...">
|
91
|
+
rename :name
|
92
|
+
end
|
93
|
+
|
94
|
+
# if you want to add your own shorthands, go nuts:
|
95
|
+
tag :activity do
|
96
|
+
rename :parent => :parentActivityName
|
97
|
+
end
|
98
|
+
|
99
|
+
# global changes
|
100
|
+
all do
|
101
|
+
rename :style # always style="", never android:style=""
|
102
|
+
end
|
103
|
+
|
104
|
+
# adds the xmlns attribute to the root node, no matter WHAT the root node is
|
105
|
+
root do
|
106
|
+
defaults 'xmlns:android' => 'http://schemas.android.com/apk/res/android'
|
107
|
+
end
|
108
|
+
|
109
|
+
# disable the xmlns attribute on the resource node
|
110
|
+
tag :resources do
|
111
|
+
defaults 'xmlns:android' => nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
# Errata
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
# If you want to check the output before committing to `write_all`
|
120
|
+
AndroidXml.output_all
|
121
|
+
|
122
|
+
# If you want to wipe out all the defaults and settings
|
123
|
+
AndroidXml.reset
|
124
|
+
|
125
|
+
# If you want the defaults back
|
126
|
+
AndroidXml.setup_defaults
|
127
|
+
```
|
data/lib/android-xml.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
module AndroidXml
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def setup_defaults
|
8
|
+
setup do
|
9
|
+
# assign the xmlns to all root nodes
|
10
|
+
root do
|
11
|
+
defaults 'xmlns:android' => 'http://schemas.android.com/apk/res/android'
|
12
|
+
end
|
13
|
+
|
14
|
+
all do
|
15
|
+
# suppress 'android:' prefix to all style attributes
|
16
|
+
rename :style
|
17
|
+
end
|
18
|
+
|
19
|
+
# disable the xmlns attribute on the resource node
|
20
|
+
tag :resources do
|
21
|
+
defaults 'xmlns:android' => nil
|
22
|
+
end
|
23
|
+
|
24
|
+
# remove the 'android:' prefix
|
25
|
+
tag :string, :style, :item do
|
26
|
+
rename :name
|
27
|
+
end
|
28
|
+
tag :style do
|
29
|
+
rename :parent
|
30
|
+
end
|
31
|
+
tag :manifest do
|
32
|
+
rename :package
|
33
|
+
end
|
34
|
+
|
35
|
+
# creates a couple "tag shortcuts"
|
36
|
+
tag :main_action => 'action' do
|
37
|
+
defaults name: 'android.intent.action.MAIN'
|
38
|
+
end
|
39
|
+
tag :launcher_category => 'category' do
|
40
|
+
defaults name: 'android.intent.category.LAUNCHER'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module AndroidXml
|
2
|
+
|
3
|
+
class XmlFile < Tag
|
4
|
+
|
5
|
+
attr :filename
|
6
|
+
|
7
|
+
def initialize(filename, &block)
|
8
|
+
@filename = filename
|
9
|
+
super(nil, &block)
|
10
|
+
AndroidXml.files << self
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(method_name, *args, &block)
|
14
|
+
raise "There can be only one (new: #{method_name}, old: #{@root})" if @root
|
15
|
+
|
16
|
+
@root = super
|
17
|
+
@root.is_root = true
|
18
|
+
@root
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate
|
22
|
+
output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
23
|
+
output << "<!-- Do not edit this file. It was generated by AndroidXml -->\n"
|
24
|
+
output << generate_block
|
25
|
+
end
|
26
|
+
|
27
|
+
def out
|
28
|
+
puts "---- filename: #{@filename} ----"
|
29
|
+
super
|
30
|
+
puts "---------------#{'-' * @filename.to_s.length}-----"
|
31
|
+
end
|
32
|
+
|
33
|
+
def write
|
34
|
+
File.open(self.filename, 'w') do |f|
|
35
|
+
f.write(self.to_s)
|
36
|
+
end
|
37
|
+
puts "✓ #{self.filename}"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module AndroidXml
|
2
|
+
ROOT = '__root_node_with_a_long_special_name__'
|
3
|
+
ALL = '__all_node_with_a_long_special_name__'
|
4
|
+
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def tab=(value)
|
8
|
+
@tab = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def file(filename, &block)
|
12
|
+
XmlFile.new(filename, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def files
|
16
|
+
@files ||= []
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_all
|
20
|
+
files.each do |xml_file|
|
21
|
+
xml_file.write
|
22
|
+
end
|
23
|
+
|
24
|
+
@files = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def output_all
|
28
|
+
files.each do |xml_file|
|
29
|
+
xml_file.out
|
30
|
+
puts
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def diff_all
|
35
|
+
files.each do |xml_file|
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def tags
|
40
|
+
@tags ||= Hash.new do |hash, key|
|
41
|
+
hash[key] = {
|
42
|
+
attrs: {},
|
43
|
+
defaults: {},
|
44
|
+
rename: nil,
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def tab
|
50
|
+
@tab ||= ' '
|
51
|
+
end
|
52
|
+
|
53
|
+
def reset
|
54
|
+
@tab = nil
|
55
|
+
@tags = nil
|
56
|
+
@files = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def setup(&block)
|
60
|
+
instance_exec(&block)
|
61
|
+
end
|
62
|
+
|
63
|
+
def root_tag
|
64
|
+
tags[ROOT]
|
65
|
+
end
|
66
|
+
|
67
|
+
def root(&block)
|
68
|
+
tag(ROOT, &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def all_tag
|
72
|
+
tags[ALL]
|
73
|
+
end
|
74
|
+
|
75
|
+
def all(&block)
|
76
|
+
tag(ALL, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
def tag(*names, &block)
|
80
|
+
context_was = @context
|
81
|
+
|
82
|
+
names.each do |name|
|
83
|
+
if name.is_a?(Hash)
|
84
|
+
@context = nil
|
85
|
+
name.each do |shortcut, tag_name|
|
86
|
+
raise "There can be only one key-value pair" if @context
|
87
|
+
|
88
|
+
@context = shortcut.to_s
|
89
|
+
tags[@context][:rename] = tag_name.to_s
|
90
|
+
end
|
91
|
+
else
|
92
|
+
@context = name.to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
instance_exec(&block)
|
96
|
+
end
|
97
|
+
|
98
|
+
@context = context_was
|
99
|
+
end
|
100
|
+
|
101
|
+
def rename(attrs)
|
102
|
+
if attrs.is_a?(Hash)
|
103
|
+
attrs.each do |attr_name, attr_rename|
|
104
|
+
tags[@context][:attrs][attr_name.to_s] = attr_rename.to_s
|
105
|
+
end
|
106
|
+
else
|
107
|
+
tags[@context][:attrs][attrs.to_s] = attrs.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def defaults(attrs)
|
112
|
+
tags[@context][:defaults].merge!(attrs)
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module AndroidXml
|
2
|
+
|
3
|
+
class Tag
|
4
|
+
attr_accessor :is_root
|
5
|
+
|
6
|
+
def initialize(tag, *args, &block)
|
7
|
+
@buffer = []
|
8
|
+
@attrs = {}
|
9
|
+
@raw_tag = tag.to_s
|
10
|
+
@text = nil
|
11
|
+
|
12
|
+
if rename = AndroidXml.tags[tag.to_s][:rename]
|
13
|
+
@tag = rename
|
14
|
+
else
|
15
|
+
@tag = tag.to_s.gsub('_', '-')
|
16
|
+
end
|
17
|
+
|
18
|
+
args.each do |arg|
|
19
|
+
if arg.is_a?(Hash)
|
20
|
+
@attrs.merge!(arg)
|
21
|
+
elsif arg.is_a?(String)
|
22
|
+
@text = arg
|
23
|
+
else
|
24
|
+
raise ArgumentError.new("Unknown argument #{arg.inspect} in #{self.class}#new")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@generate = block
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method_name, *args, &block)
|
32
|
+
tag = Tag.new(method_name, *args, &block)
|
33
|
+
@buffer << tag
|
34
|
+
tag
|
35
|
+
end
|
36
|
+
|
37
|
+
def attrs(whitespace)
|
38
|
+
attrs = {}
|
39
|
+
|
40
|
+
attrs.merge!(AndroidXml.all_tag[:defaults])
|
41
|
+
if is_root
|
42
|
+
attrs.merge!(AndroidXml.root_tag[:defaults])
|
43
|
+
end
|
44
|
+
|
45
|
+
attrs.merge!(AndroidXml.tags[@raw_tag][:defaults])
|
46
|
+
attrs.merge!(@attrs)
|
47
|
+
|
48
|
+
output = ''
|
49
|
+
is_first = true
|
50
|
+
attrs.each do |key, value|
|
51
|
+
next if value.nil?
|
52
|
+
|
53
|
+
key = key.to_s
|
54
|
+
|
55
|
+
if AndroidXml.tags[@tag][:attrs].key?(key)
|
56
|
+
xml_key = AndroidXml.tags[@tag][:attrs][key]
|
57
|
+
elsif AndroidXml.all_tag[:attrs].key?(key)
|
58
|
+
xml_key = AndroidXml.all_tag[:attrs][key]
|
59
|
+
elsif key.to_s.include?(':')
|
60
|
+
xml_key = key.to_s
|
61
|
+
else
|
62
|
+
xml_key = "android:#{key}"
|
63
|
+
end
|
64
|
+
|
65
|
+
if is_first
|
66
|
+
output << " #{xml_key}=\"#{value}\""
|
67
|
+
is_first = false
|
68
|
+
else
|
69
|
+
output << "\n#{whitespace}#{xml_key}=\"#{value}\""
|
70
|
+
end
|
71
|
+
end
|
72
|
+
output
|
73
|
+
end
|
74
|
+
|
75
|
+
def generate(tab='')
|
76
|
+
whitespace = "#{tab} #{' ' * @tag.length}"
|
77
|
+
output = "#{tab}<#{@tag}#{attrs(whitespace)}"
|
78
|
+
if @generate
|
79
|
+
inside = generate_block(tab + AndroidXml.tab)
|
80
|
+
if !inside || inside.strip.empty?
|
81
|
+
output << " />\n"
|
82
|
+
else
|
83
|
+
output << ">"
|
84
|
+
if inside.lstrip.start_with?('<')
|
85
|
+
output << "\n" << inside << "#{tab}</#{@tag}>\n"
|
86
|
+
else
|
87
|
+
output << inside << "</#{@tag}>\n"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
output << " />\n"
|
92
|
+
end
|
93
|
+
|
94
|
+
output
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate_block(tab='')
|
98
|
+
return @block_output if @block_output
|
99
|
+
|
100
|
+
output = ''
|
101
|
+
if @generate
|
102
|
+
text = instance_exec(&@generate)
|
103
|
+
@buffer.each do |tag|
|
104
|
+
output << tag.generate(tab)
|
105
|
+
end
|
106
|
+
if text.is_a?(String)
|
107
|
+
if output.empty?
|
108
|
+
output << text
|
109
|
+
else
|
110
|
+
output << tab << text << "\n"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
@block_output = output
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_s
|
119
|
+
generate
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_ary
|
123
|
+
[to_s]
|
124
|
+
end
|
125
|
+
|
126
|
+
def out
|
127
|
+
puts to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'AndroidManifest.xml' do
|
5
|
+
|
6
|
+
before do
|
7
|
+
AndroidXml.reset
|
8
|
+
AndroidXml.setup_defaults
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should generate a sensible AndroidManifest file' do
|
12
|
+
xml = AndroidXml.file('AndroidManifest.xml') do
|
13
|
+
manifest package: 'com.your_name_here.AnyAndroidApp', versionCode: 1, versionName: 1.0 do
|
14
|
+
uses_sdk minSdkVersion: 11
|
15
|
+
|
16
|
+
application label: '@string/app_name', icon: '@drawable/ic_launcher' do
|
17
|
+
activity name: 'MainActivity', label: '@string/app_name' do
|
18
|
+
intent_filter do
|
19
|
+
main_action
|
20
|
+
launcher_category
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
activity name: 'AnotherActivity', label: '@string/app_name', parentActivityName: 'com.your_name_here.AnyAndroidApp.MainActivity'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(xml.to_s).to eql <<-XML
|
30
|
+
<?xml version="1.0" encoding="utf-8"?>
|
31
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
32
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
33
|
+
package="com.your_name_here.AnyAndroidApp"
|
34
|
+
android:versionCode="1"
|
35
|
+
android:versionName="1.0">
|
36
|
+
<uses-sdk android:minSdkVersion="11" />
|
37
|
+
<application android:label="@string/app_name"
|
38
|
+
android:icon="@drawable/ic_launcher">
|
39
|
+
<activity android:name="MainActivity"
|
40
|
+
android:label="@string/app_name">
|
41
|
+
<intent-filter>
|
42
|
+
<action android:name="android.intent.action.MAIN" />
|
43
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
44
|
+
</intent-filter>
|
45
|
+
</activity>
|
46
|
+
<activity android:name="AnotherActivity"
|
47
|
+
android:label="@string/app_name"
|
48
|
+
android:parentActivityName="com.your_name_here.AnyAndroidApp.MainActivity" />
|
49
|
+
</application>
|
50
|
+
</manifest>
|
51
|
+
XML
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'Android menu files' do
|
5
|
+
|
6
|
+
before do
|
7
|
+
AndroidXml.reset
|
8
|
+
AndroidXml.setup_defaults
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should generate a sensible menu.xml file' do
|
12
|
+
xml = AndroidXml.file('res/menu/menu.xml') do
|
13
|
+
menu do
|
14
|
+
item id: '@+id/action_search',
|
15
|
+
icon: '@drawable/ic_action_search',
|
16
|
+
title: '@string/action_search',
|
17
|
+
showAsAction: 'ifRoom'
|
18
|
+
|
19
|
+
item id: '@+id/action_settings',
|
20
|
+
title: '@string/action_settings',
|
21
|
+
showAsAction: 'never'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
expect(xml.to_s).to eql <<-XML
|
26
|
+
<?xml version="1.0" encoding="utf-8"?>
|
27
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
28
|
+
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
29
|
+
<item android:id="@+id/action_search"
|
30
|
+
android:icon="@drawable/ic_action_search"
|
31
|
+
android:title="@string/action_search"
|
32
|
+
android:showAsAction="ifRoom" />
|
33
|
+
<item android:id="@+id/action_settings"
|
34
|
+
android:title="@string/action_settings"
|
35
|
+
android:showAsAction="never" />
|
36
|
+
</menu>
|
37
|
+
XML
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should generate a sensible strings.xml file' do
|
41
|
+
xml = AndroidXml.file('res/values/strings.xml') do
|
42
|
+
resources do
|
43
|
+
string(name: 'app_name') { 'Harroo' }
|
44
|
+
string(name: 'hello') { 'Well, Harroo!' }
|
45
|
+
string(name: 'portrait') { 'portrait' }
|
46
|
+
string(name: 'landscape') { 'landscape' }
|
47
|
+
string(name: 'button_send') { 'Send' }
|
48
|
+
string(name: 'action_search') { 'Search' }
|
49
|
+
string(name: 'action_settings') { 'Settings' }
|
50
|
+
string(name: 'title_activity_main') { 'MainActivity' }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
expect(xml.to_s).to eql <<-XML
|
55
|
+
<?xml version="1.0" encoding="utf-8"?>
|
56
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
57
|
+
<resources>
|
58
|
+
<string name="app_name">Harroo</string>
|
59
|
+
<string name="hello">Well, Harroo!</string>
|
60
|
+
<string name="portrait">portrait</string>
|
61
|
+
<string name="landscape">landscape</string>
|
62
|
+
<string name="button_send">Send</string>
|
63
|
+
<string name="action_search">Search</string>
|
64
|
+
<string name="action_settings">Settings</string>
|
65
|
+
<string name="title_activity_main">MainActivity</string>
|
66
|
+
</resources>
|
67
|
+
XML
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'Android resource files' do
|
5
|
+
|
6
|
+
before do
|
7
|
+
AndroidXml.reset
|
8
|
+
AndroidXml.setup_defaults
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should generate a sensible style.xml file' do
|
12
|
+
xml = AndroidXml.file('res/values/style.xml') do
|
13
|
+
resources do
|
14
|
+
style(name: 'CodeFont', parent: '@android:style/TextAppearance.Medium') do
|
15
|
+
item(name: "android:layout_width") { 'fill_parent' }
|
16
|
+
item(name: "android:layout_height") { 'wrap_content' }
|
17
|
+
item(name: "android:textColor") { '#00FF00' }
|
18
|
+
item(name: "android:typeface") { 'monospace' }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
expect(xml.to_s).to eql <<-XML
|
24
|
+
<?xml version="1.0" encoding="utf-8"?>
|
25
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
26
|
+
<resources>
|
27
|
+
<style name="CodeFont"
|
28
|
+
parent="@android:style/TextAppearance.Medium">
|
29
|
+
<item name="android:layout_width">fill_parent</item>
|
30
|
+
<item name="android:layout_height">wrap_content</item>
|
31
|
+
<item name="android:textColor">#00FF00</item>
|
32
|
+
<item name="android:typeface">monospace</item>
|
33
|
+
</style>
|
34
|
+
</resources>
|
35
|
+
XML
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should generate a sensible strings.xml file' do
|
39
|
+
xml = AndroidXml.file('res/values/strings.xml') do
|
40
|
+
resources do
|
41
|
+
string(name: 'app_name') { 'Harroo' }
|
42
|
+
string(name: 'hello') { 'Well, Harroo!' }
|
43
|
+
string(name: 'portrait') { 'portrait' }
|
44
|
+
string(name: 'landscape') { 'landscape' }
|
45
|
+
string(name: 'button_send') { 'Send' }
|
46
|
+
string(name: 'action_search') { 'Search' }
|
47
|
+
string(name: 'action_settings') { 'Settings' }
|
48
|
+
string(name: 'title_activity_main') { 'MainActivity' }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
expect(xml.to_s).to eql <<-XML
|
53
|
+
<?xml version="1.0" encoding="utf-8"?>
|
54
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
55
|
+
<resources>
|
56
|
+
<string name="app_name">Harroo</string>
|
57
|
+
<string name="hello">Well, Harroo!</string>
|
58
|
+
<string name="portrait">portrait</string>
|
59
|
+
<string name="landscape">landscape</string>
|
60
|
+
<string name="button_send">Send</string>
|
61
|
+
<string name="action_search">Search</string>
|
62
|
+
<string name="action_settings">Settings</string>
|
63
|
+
<string name="title_activity_main">MainActivity</string>
|
64
|
+
</resources>
|
65
|
+
XML
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
describe AndroidXml do
|
4
|
+
|
5
|
+
before do
|
6
|
+
AndroidXml.reset
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should generate <any-tag />' do
|
10
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
11
|
+
any_tag
|
12
|
+
end
|
13
|
+
|
14
|
+
expect(xml.to_s).to eql <<-XML
|
15
|
+
<?xml version="1.0" encoding="utf-8"?>
|
16
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
17
|
+
<any-tag />
|
18
|
+
XML
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should generate <any-tag with="properties" />' do
|
22
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
23
|
+
any_tag with: 'properties'
|
24
|
+
end
|
25
|
+
|
26
|
+
expect(xml.to_s).to eql <<-XML
|
27
|
+
<?xml version="1.0" encoding="utf-8"?>
|
28
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
29
|
+
<any-tag android:with="properties" />
|
30
|
+
XML
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should generate <any-tag>with text</any-tag>' do
|
34
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
35
|
+
any_tag { 'with text' }
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(xml.to_s).to eql <<-XML
|
39
|
+
<?xml version="1.0" encoding="utf-8"?>
|
40
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
41
|
+
<any-tag>with text</any-tag>
|
42
|
+
XML
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should generate <nested><tags /></nested>' do
|
46
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
47
|
+
nested do
|
48
|
+
tags
|
49
|
+
tags
|
50
|
+
tags
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
expect(xml.to_s).to eql <<-XML
|
55
|
+
<?xml version="1.0" encoding="utf-8"?>
|
56
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
57
|
+
<nested>
|
58
|
+
<tags />
|
59
|
+
<tags />
|
60
|
+
<tags />
|
61
|
+
</nested>
|
62
|
+
XML
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should generate <nested><tags /></nested> with custom whitespace' do
|
66
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
67
|
+
nested do
|
68
|
+
tags
|
69
|
+
tags
|
70
|
+
tags
|
71
|
+
end
|
72
|
+
end
|
73
|
+
AndroidXml.tab = ' '
|
74
|
+
|
75
|
+
expect(xml.to_s).to eql <<-XML
|
76
|
+
<?xml version="1.0" encoding="utf-8"?>
|
77
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
78
|
+
<nested>
|
79
|
+
<tags />
|
80
|
+
<tags />
|
81
|
+
<tags />
|
82
|
+
</nested>
|
83
|
+
XML
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should generate <nested><tags />with text</nested>' do
|
87
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
88
|
+
nested do
|
89
|
+
tags
|
90
|
+
tags
|
91
|
+
'with text'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
expect(xml.to_s).to eql <<-XML
|
96
|
+
<?xml version="1.0" encoding="utf-8"?>
|
97
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
98
|
+
<nested>
|
99
|
+
<tags />
|
100
|
+
<tags />
|
101
|
+
with text
|
102
|
+
</nested>
|
103
|
+
XML
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should generate <nested with="" many="properties"><tags with="" many="properties" /></nested>' do
|
107
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
108
|
+
nested with: '', many: 'properties' do
|
109
|
+
tags with: '', many: 'properties'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
expect(xml.to_s).to eql <<-XML
|
114
|
+
<?xml version="1.0" encoding="utf-8"?>
|
115
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
116
|
+
<nested android:with=""
|
117
|
+
android:many="properties">
|
118
|
+
<tags android:with=""
|
119
|
+
android:many="properties" />
|
120
|
+
</nested>
|
121
|
+
XML
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: android-xml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Colin T.A. Gray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: |
|
28
|
+
Add this to your build process, and never write XML again!
|
29
|
+
|
30
|
+
Plus, you can have multiple files generated from one file.
|
31
|
+
email:
|
32
|
+
- colinta@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- lib/android-xml/defaults.rb
|
38
|
+
- lib/android-xml/file.rb
|
39
|
+
- lib/android-xml/main.rb
|
40
|
+
- lib/android-xml/tag.rb
|
41
|
+
- lib/android-xml/version.rb
|
42
|
+
- lib/android-xml.rb
|
43
|
+
- README.md
|
44
|
+
- spec/android_manifest_spec.rb
|
45
|
+
- spec/android_menu_spec.rb
|
46
|
+
- spec/android_resources_spec.rb
|
47
|
+
- spec/generate_spec.rb
|
48
|
+
homepage: https://github.com/colinta/android-xml
|
49
|
+
licenses:
|
50
|
+
- BSD
|
51
|
+
metadata: {}
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.0.3
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: Generates Android XML files.
|
72
|
+
test_files:
|
73
|
+
- spec/android_manifest_spec.rb
|
74
|
+
- spec/android_menu_spec.rb
|
75
|
+
- spec/android_resources_spec.rb
|
76
|
+
- spec/generate_spec.rb
|