confetti 0.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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +48 -0
- data/README.md +46 -0
- data/Rakefile +19 -0
- data/bin/confetti +4 -0
- data/confetti.gemspec +29 -0
- data/features/android.feature +14 -0
- data/features/blackberry.feature +9 -0
- data/features/command_line.feature +12 -0
- data/features/ios.feature +9 -0
- data/features/step_definitions/aruba_ext_steps.rb +7 -0
- data/features/support/setup.rb +1 -0
- data/features/symbian.wrt.feature +9 -0
- data/features/webos.feature +9 -0
- data/lib/confetti.rb +31 -0
- data/lib/confetti/cli.rb +19 -0
- data/lib/confetti/config.rb +57 -0
- data/lib/confetti/config/feature.rb +13 -0
- data/lib/confetti/helpers.rb +7 -0
- data/lib/confetti/template.rb +4 -0
- data/lib/confetti/template_helper.rb +28 -0
- data/lib/confetti/templates/android_manifest.mustache +33 -0
- data/lib/confetti/templates/android_manifest.rb +27 -0
- data/lib/confetti/templates/android_strings.mustache +5 -0
- data/lib/confetti/templates/android_strings.rb +13 -0
- data/lib/confetti/templates/base.mustache +0 -0
- data/lib/confetti/templates/base.rb +13 -0
- data/lib/confetti/templates/blackberry_widgets_config.mustache +20 -0
- data/lib/confetti/templates/blackberry_widgets_config.rb +37 -0
- data/lib/confetti/templates/ios_info.mustache +48 -0
- data/lib/confetti/templates/ios_info.rb +21 -0
- data/lib/confetti/templates/java_checks.rb +18 -0
- data/lib/confetti/templates/symbian_wrt_info.mustache +17 -0
- data/lib/confetti/templates/symbian_wrt_info.rb +21 -0
- data/lib/confetti/templates/webos_appinfo.mustache +9 -0
- data/lib/confetti/templates/webos_appinfo.rb +49 -0
- data/lib/confetti/version.rb +3 -0
- data/lib/typedset.rb +23 -0
- data/spec/config/config_author_spec.rb +22 -0
- data/spec/config/config_content_spec.rb +22 -0
- data/spec/config/config_feature_spec.rb +33 -0
- data/spec/config/config_icon_spec.rb +22 -0
- data/spec/config/config_license_spec.rb +17 -0
- data/spec/config/config_name_spec.rb +17 -0
- data/spec/config/config_preference_spec.rb +22 -0
- data/spec/config_spec.rb +217 -0
- data/spec/fixtures/AndroidManifest_expected.xml +33 -0
- data/spec/fixtures/android_manifest_spec.xml +33 -0
- data/spec/fixtures/android_strings_expected.xml +5 -0
- data/spec/fixtures/android_strings_spec.xml +5 -0
- data/spec/fixtures/appinfo_expected.json +9 -0
- data/spec/fixtures/blackberry_widget_config_expected.xml +20 -0
- data/spec/fixtures/blackberry_widget_config_spec.xml +20 -0
- data/spec/fixtures/config.xml +21 -0
- data/spec/fixtures/ios_info_expected.plist +48 -0
- data/spec/fixtures/ios_info_spec.plist +48 -0
- data/spec/fixtures/symbian_wrt_info_expected.plist +17 -0
- data/spec/fixtures/symbian_wrt_info_spec.plist +17 -0
- data/spec/fixtures/webos_appinfo_spec.json +9 -0
- data/spec/helpers_spec.rb +21 -0
- data/spec/integration_spec.rb +66 -0
- data/spec/spec_helper.rb +83 -0
- data/spec/template_spec.rb +4 -0
- data/spec/templates/android_manifest_spec.rb +66 -0
- data/spec/templates/android_strings_spec.rb +56 -0
- data/spec/templates/base_spec.rb +25 -0
- data/spec/templates/blackberry_widget_config_spec.rb +94 -0
- data/spec/templates/ios_info_spec.rb +68 -0
- data/spec/templates/java_checks_spec.rb +59 -0
- data/spec/templates/symbian_wrt_info_spec.rb +68 -0
- data/spec/templates/webos_appinfo_spec.rb +101 -0
- data/spec/typedset_spec.rb +72 -0
- metadata +256 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
confetti (0.1.0)
|
5
|
+
mustache (= 0.11.2)
|
6
|
+
thor (= 0.14.3)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
aruba (0.2.6)
|
12
|
+
background_process
|
13
|
+
cucumber (~> 0.9.4)
|
14
|
+
background_process (1.2)
|
15
|
+
builder (2.1.2)
|
16
|
+
cucumber (0.9.4)
|
17
|
+
builder (~> 2.1.2)
|
18
|
+
diff-lcs (~> 1.1.2)
|
19
|
+
gherkin (~> 2.2.9)
|
20
|
+
json (~> 1.4.6)
|
21
|
+
term-ansicolor (~> 1.0.5)
|
22
|
+
diff-lcs (1.1.2)
|
23
|
+
gherkin (2.2.9)
|
24
|
+
json (~> 1.4.6)
|
25
|
+
term-ansicolor (~> 1.0.5)
|
26
|
+
json (1.4.6)
|
27
|
+
mustache (0.11.2)
|
28
|
+
rspec (2.1.0)
|
29
|
+
rspec-core (~> 2.1.0)
|
30
|
+
rspec-expectations (~> 2.1.0)
|
31
|
+
rspec-mocks (~> 2.1.0)
|
32
|
+
rspec-core (2.1.0)
|
33
|
+
rspec-expectations (2.1.0)
|
34
|
+
diff-lcs (~> 1.1.2)
|
35
|
+
rspec-mocks (2.1.0)
|
36
|
+
term-ansicolor (1.0.5)
|
37
|
+
thor (0.14.3)
|
38
|
+
|
39
|
+
PLATFORMS
|
40
|
+
ruby
|
41
|
+
|
42
|
+
DEPENDENCIES
|
43
|
+
aruba
|
44
|
+
confetti!
|
45
|
+
cucumber
|
46
|
+
mustache (= 0.11.2)
|
47
|
+
rspec (~> 2.1.0)
|
48
|
+
thor (= 0.14.3)
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Confetti
|
2
|
+
|
3
|
+
## How to Add a New Platform
|
4
|
+
|
5
|
+
Let's say you want write a `nintendo_ds_config` generator:
|
6
|
+
|
7
|
+
* create a feature file, like `features/nintendo.feature`
|
8
|
+
* specify all the files to generate for your platform
|
9
|
+
* specify the name each file will go under
|
10
|
+
* `nintendo_ds_config`
|
11
|
+
* and the default filename
|
12
|
+
* `NintendoDSConfig.xml`
|
13
|
+
* run `rake features` to verify that it fails
|
14
|
+
* add a sample configuration file to `spec/fixtures`
|
15
|
+
* the filename is based on the descriptive name
|
16
|
+
* `nintendo_ds_config_expected.xml`
|
17
|
+
* add some failing specs
|
18
|
+
* copy one of the existing specs from `spec/templates`
|
19
|
+
* `cp android_manifest_spec.rb nintendo_ds_config_spec.rb`
|
20
|
+
* modify the new file to match your new template
|
21
|
+
* this isn't as well automated as we'd like
|
22
|
+
* run `rake spec` to verify that they fail
|
23
|
+
* create your view class
|
24
|
+
* as `lib/confetti/templates/nintendo_ds_config.rb`
|
25
|
+
* should define `Confetti::Template::NintendoDsConfig < Base`
|
26
|
+
* create your template file
|
27
|
+
* copy your expected config into `lib/confetti/templates`
|
28
|
+
* as `nintendo_ds_config.mustache`
|
29
|
+
* replace the variable sections with mustache tags
|
30
|
+
* in your view class
|
31
|
+
* write methods that correspond to the variable sections in your template
|
32
|
+
* run `rake spec` to ensure everything was set up correctly
|
33
|
+
* add specs for generate and write methods
|
34
|
+
* open `spec/config_spec.rb`
|
35
|
+
* add the following line to the `describe config generation` block
|
36
|
+
* `it_should_have_generate_and_write_methods_for :nintendo_ds_config`
|
37
|
+
* run `rake spec`, see them fail
|
38
|
+
* add generate and write methods
|
39
|
+
* open lib/confetti/config.rb
|
40
|
+
* add your platform to the `generate_and_write` call
|
41
|
+
* `generate_and_write ... :nintendo_ds_config`
|
42
|
+
* run `rake spec` again
|
43
|
+
* build and install the gem, or whatever, so the cucumber tests work
|
44
|
+
* run `feature/nintendo.feature`
|
45
|
+
* it's all green!
|
46
|
+
* you're the man now dog
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
desc "run all specs"
|
5
|
+
task :spec do
|
6
|
+
system "bundle exec rspec spec"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "run all cucumber features"
|
10
|
+
task :features do
|
11
|
+
system "bundle exec cucumber features"
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :spec do
|
15
|
+
# more spec running tasks here
|
16
|
+
# whenever
|
17
|
+
end
|
18
|
+
|
19
|
+
task :default => [:features, :spec]
|
data/bin/confetti
ADDED
data/confetti.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "confetti/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "confetti"
|
7
|
+
s.version = Confetti::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Andrew Lunny"]
|
10
|
+
s.email = ["alunny@gmail.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/confetti"
|
12
|
+
s.summary = %q{Generate mobile app config files}
|
13
|
+
s.description = %q{ A little library to generate platform-specific mobile app
|
14
|
+
configuration files from a W3C widget spec compliant config.xml}
|
15
|
+
|
16
|
+
s.rubyforge_project = "confetti"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_dependency "mustache", "0.11.2"
|
24
|
+
s.add_dependency "thor", "0.14.3"
|
25
|
+
|
26
|
+
s.add_development_dependency "rspec", "~> 2.1.0"
|
27
|
+
s.add_development_dependency "cucumber"
|
28
|
+
s.add_development_dependency "aruba"
|
29
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Android
|
2
|
+
In order to build Android Apps
|
3
|
+
As a Mobile Developer
|
4
|
+
I want to generate Android configuration files
|
5
|
+
|
6
|
+
Scenario: I need an AndroidManifest
|
7
|
+
When I have a config.xml file
|
8
|
+
And I run "confetti generate android_manifest"
|
9
|
+
Then a file named "AndroidManifest.xml" should exist
|
10
|
+
|
11
|
+
Scenario: I need an Android strings.xml file
|
12
|
+
When I have a config.xml file
|
13
|
+
And I run "confetti generate android_strings"
|
14
|
+
Then a file named "strings.xml" should exist
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: Blackberry
|
2
|
+
In order to build Blackberry Apps
|
3
|
+
As a Mobile Developer
|
4
|
+
I want to generate whatever config files are required
|
5
|
+
|
6
|
+
Scenario: I need a (BB widget) config.xml
|
7
|
+
When I have a config.xml file
|
8
|
+
And I run "confetti generate blackberry_widgets_config"
|
9
|
+
Then a file named "bb-config.xml" should exist
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Feature: Command Line
|
2
|
+
In order to generate mobile configurations
|
3
|
+
As a PhoneGap Developer
|
4
|
+
I want to use the Confetti CLI
|
5
|
+
|
6
|
+
Scenario: I want an unsupported type
|
7
|
+
When I have a config.xml file
|
8
|
+
And I run "confetti generate microsoft_word"
|
9
|
+
Then it should fail with:
|
10
|
+
"""
|
11
|
+
microsoft_word unsupported
|
12
|
+
"""
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: iOS
|
2
|
+
In order to build iOS Apps
|
3
|
+
As a Mobile Developer
|
4
|
+
I want to generate the iOS configuration files
|
5
|
+
|
6
|
+
Scenario: I need an Info.plist
|
7
|
+
When I have a config.xml file
|
8
|
+
And I run "confetti generate ios_info"
|
9
|
+
Then a file named "Info.plist" should exist
|
@@ -0,0 +1,7 @@
|
|
1
|
+
When /^I have a config.xml file$/ do
|
2
|
+
fixtures_dir = File.join(File.dirname(__FILE__), '..', '..', 'spec', 'fixtures')
|
3
|
+
fixtures_dir = File.expand_path(fixtures_dir)
|
4
|
+
config_fixture = File.read(File.join(fixtures_dir, "config.xml"))
|
5
|
+
|
6
|
+
create_file("config.xml", config_fixture)
|
7
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "aruba"
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: Symbian.wrt
|
2
|
+
In order to build Symbian.wrt Apps
|
3
|
+
As a Mobile Developer
|
4
|
+
I want to generate the Symbian.wrt configuration files
|
5
|
+
|
6
|
+
Scenario: I need an info.plist
|
7
|
+
When I have a config.xml file
|
8
|
+
And I run "confetti generate symbian_wrt_info"
|
9
|
+
Then a file named "info.plist" should exist
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: webOS
|
2
|
+
In order to build webOS Apps
|
3
|
+
As a Mobile Developer
|
4
|
+
I want to generate the webOS configuration files
|
5
|
+
|
6
|
+
Scenario: I need a appinfo.json
|
7
|
+
When I have a config.xml file
|
8
|
+
And I run "confetti generate webos_appinfo"
|
9
|
+
Then a file named "appinfo.json" should exist
|
data/lib/confetti.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
CURRENT_DIR = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
# stdlib
|
4
|
+
require "rexml/document"
|
5
|
+
|
6
|
+
# external dependencies
|
7
|
+
begin
|
8
|
+
require "bundler/setup"
|
9
|
+
rescue LoadError
|
10
|
+
require "rubygems"
|
11
|
+
require "bundler/setup"
|
12
|
+
end
|
13
|
+
|
14
|
+
require "thor"
|
15
|
+
require "mustache"
|
16
|
+
|
17
|
+
# internal dependencies
|
18
|
+
require 'typedset'
|
19
|
+
require 'confetti/version'
|
20
|
+
require 'confetti/helpers'
|
21
|
+
|
22
|
+
require 'confetti/template'
|
23
|
+
require 'confetti/templates/base'
|
24
|
+
require 'confetti/templates/java_checks'
|
25
|
+
Dir[File.join(CURRENT_DIR, 'confetti', 'templates', '*')].each do |file|
|
26
|
+
require file if File.extname(file) == ".rb"
|
27
|
+
end
|
28
|
+
require 'confetti/template_helper'
|
29
|
+
|
30
|
+
require 'confetti/config'
|
31
|
+
require 'confetti/config/feature'
|
data/lib/confetti/cli.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "confetti"
|
2
|
+
|
3
|
+
module Confetti
|
4
|
+
class CLI < Thor
|
5
|
+
desc "generate OUTPUT_FILE", "Generates a config file of type OUTPUT_FILE"
|
6
|
+
def generate(output_file)
|
7
|
+
config_xml = File.join(Dir.pwd, "config.xml")
|
8
|
+
|
9
|
+
config = Confetti::Config.new(config_xml)
|
10
|
+
msg = "write_#{ output_file }".to_sym
|
11
|
+
|
12
|
+
begin
|
13
|
+
config.send msg
|
14
|
+
rescue
|
15
|
+
fail "Confetti Failed: format #{ output_file } unsupported"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Confetti
|
2
|
+
class Config
|
3
|
+
include Helpers
|
4
|
+
self.extend TemplateHelper
|
5
|
+
|
6
|
+
attr_accessor :package, :version, :description, :height, :width
|
7
|
+
attr_reader :author, :viewmodes, :name, :license, :content,
|
8
|
+
:icon_set, :feature_set, :preference_set
|
9
|
+
|
10
|
+
generate_and_write :android_manifest, :android_strings, :webos_appinfo,
|
11
|
+
:ios_info, :symbian_wrt_info, :blackberry_widgets_config
|
12
|
+
|
13
|
+
# classes that represent child elements
|
14
|
+
Author = Class.new Struct.new(:name, :href, :email)
|
15
|
+
Name = Class.new Struct.new(:name, :shortname)
|
16
|
+
License = Class.new Struct.new(:text, :href)
|
17
|
+
Content = Class.new Struct.new(:src, :type, :encoding)
|
18
|
+
Icon = Class.new Struct.new(:src, :height, :width)
|
19
|
+
Feature = Class.new Struct.new(:name, :required)
|
20
|
+
Preference = Class.new Struct.new(:name, :value, :readonly)
|
21
|
+
|
22
|
+
def initialize(*args)
|
23
|
+
@author = Author.new
|
24
|
+
@name = Name.new
|
25
|
+
@license = License.new
|
26
|
+
@content = Content.new
|
27
|
+
@icon_set = TypedSet.new Icon
|
28
|
+
@feature_set = TypedSet.new Feature
|
29
|
+
@preference_set = TypedSet.new Preference
|
30
|
+
@viewmodes = []
|
31
|
+
|
32
|
+
if args.length > 0 && is_file?(args.first)
|
33
|
+
populate_from_xml args.first
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def populate_from_xml(xml_file)
|
38
|
+
config_doc = REXML::Document.new(File.read(xml_file)).root
|
39
|
+
fail "no doc parsed" unless config_doc
|
40
|
+
|
41
|
+
@package = config_doc.attributes["id"]
|
42
|
+
@version = config_doc.attributes["version"]
|
43
|
+
|
44
|
+
config_doc.elements.each do |ele|
|
45
|
+
case ele.name
|
46
|
+
when "name"
|
47
|
+
@name = Name.new(ele.text.strip, ele.attributes["shortname"])
|
48
|
+
when "author"
|
49
|
+
@author = Author.new(ele.text.strip, ele.attributes["href"],
|
50
|
+
ele.attributes["email"])
|
51
|
+
when "description"
|
52
|
+
@description = ele.text.strip
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Confetti
|
2
|
+
module TemplateHelper
|
3
|
+
def generate_and_write (*platforms)
|
4
|
+
platforms.each do |config_type|
|
5
|
+
class_name = config_type.to_s.split("_").collect do |s|
|
6
|
+
s.capitalize
|
7
|
+
end.join
|
8
|
+
template_class = Confetti::Template.const_get(class_name)
|
9
|
+
|
10
|
+
generate_method = "generate_#{ config_type }".to_sym
|
11
|
+
write_method = "write_#{ config_type }".to_sym
|
12
|
+
|
13
|
+
send :define_method, generate_method do
|
14
|
+
template_class.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
send :define_method, write_method do |*args|
|
18
|
+
filepath = args.first
|
19
|
+
|
20
|
+
template = send generate_method
|
21
|
+
filepath ||= File.join(Dir.pwd, template.output_filename)
|
22
|
+
|
23
|
+
open(filepath, 'w') { |f| f.puts template.render }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
3
|
+
package="{{ package_name }}"
|
4
|
+
android:versionName="{{ version }}"
|
5
|
+
android:versionCode="1">
|
6
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
7
|
+
<uses-permission android:name="android.permission.VIBRATE" />
|
8
|
+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
9
|
+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
10
|
+
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
11
|
+
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
12
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
13
|
+
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
14
|
+
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
15
|
+
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
16
|
+
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
17
|
+
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
18
|
+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
19
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
20
|
+
|
21
|
+
<application android:icon="@drawable/icon" android:label="@string/app_name"
|
22
|
+
android:debuggable="true">
|
23
|
+
<activity android:name=".{{ class_name }}"
|
24
|
+
android:label="@string/app_name" android:configChanges="orientation|keyboardHidden">
|
25
|
+
<intent-filter>
|
26
|
+
<action android:name="android.intent.action.MAIN" />
|
27
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
28
|
+
</intent-filter>
|
29
|
+
</activity>
|
30
|
+
</application>
|
31
|
+
<uses-sdk android:minSdkVersion="2" />
|
32
|
+
|
33
|
+
</manifest>
|