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.
Files changed (74) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +48 -0
  4. data/README.md +46 -0
  5. data/Rakefile +19 -0
  6. data/bin/confetti +4 -0
  7. data/confetti.gemspec +29 -0
  8. data/features/android.feature +14 -0
  9. data/features/blackberry.feature +9 -0
  10. data/features/command_line.feature +12 -0
  11. data/features/ios.feature +9 -0
  12. data/features/step_definitions/aruba_ext_steps.rb +7 -0
  13. data/features/support/setup.rb +1 -0
  14. data/features/symbian.wrt.feature +9 -0
  15. data/features/webos.feature +9 -0
  16. data/lib/confetti.rb +31 -0
  17. data/lib/confetti/cli.rb +19 -0
  18. data/lib/confetti/config.rb +57 -0
  19. data/lib/confetti/config/feature.rb +13 -0
  20. data/lib/confetti/helpers.rb +7 -0
  21. data/lib/confetti/template.rb +4 -0
  22. data/lib/confetti/template_helper.rb +28 -0
  23. data/lib/confetti/templates/android_manifest.mustache +33 -0
  24. data/lib/confetti/templates/android_manifest.rb +27 -0
  25. data/lib/confetti/templates/android_strings.mustache +5 -0
  26. data/lib/confetti/templates/android_strings.rb +13 -0
  27. data/lib/confetti/templates/base.mustache +0 -0
  28. data/lib/confetti/templates/base.rb +13 -0
  29. data/lib/confetti/templates/blackberry_widgets_config.mustache +20 -0
  30. data/lib/confetti/templates/blackberry_widgets_config.rb +37 -0
  31. data/lib/confetti/templates/ios_info.mustache +48 -0
  32. data/lib/confetti/templates/ios_info.rb +21 -0
  33. data/lib/confetti/templates/java_checks.rb +18 -0
  34. data/lib/confetti/templates/symbian_wrt_info.mustache +17 -0
  35. data/lib/confetti/templates/symbian_wrt_info.rb +21 -0
  36. data/lib/confetti/templates/webos_appinfo.mustache +9 -0
  37. data/lib/confetti/templates/webos_appinfo.rb +49 -0
  38. data/lib/confetti/version.rb +3 -0
  39. data/lib/typedset.rb +23 -0
  40. data/spec/config/config_author_spec.rb +22 -0
  41. data/spec/config/config_content_spec.rb +22 -0
  42. data/spec/config/config_feature_spec.rb +33 -0
  43. data/spec/config/config_icon_spec.rb +22 -0
  44. data/spec/config/config_license_spec.rb +17 -0
  45. data/spec/config/config_name_spec.rb +17 -0
  46. data/spec/config/config_preference_spec.rb +22 -0
  47. data/spec/config_spec.rb +217 -0
  48. data/spec/fixtures/AndroidManifest_expected.xml +33 -0
  49. data/spec/fixtures/android_manifest_spec.xml +33 -0
  50. data/spec/fixtures/android_strings_expected.xml +5 -0
  51. data/spec/fixtures/android_strings_spec.xml +5 -0
  52. data/spec/fixtures/appinfo_expected.json +9 -0
  53. data/spec/fixtures/blackberry_widget_config_expected.xml +20 -0
  54. data/spec/fixtures/blackberry_widget_config_spec.xml +20 -0
  55. data/spec/fixtures/config.xml +21 -0
  56. data/spec/fixtures/ios_info_expected.plist +48 -0
  57. data/spec/fixtures/ios_info_spec.plist +48 -0
  58. data/spec/fixtures/symbian_wrt_info_expected.plist +17 -0
  59. data/spec/fixtures/symbian_wrt_info_spec.plist +17 -0
  60. data/spec/fixtures/webos_appinfo_spec.json +9 -0
  61. data/spec/helpers_spec.rb +21 -0
  62. data/spec/integration_spec.rb +66 -0
  63. data/spec/spec_helper.rb +83 -0
  64. data/spec/template_spec.rb +4 -0
  65. data/spec/templates/android_manifest_spec.rb +66 -0
  66. data/spec/templates/android_strings_spec.rb +56 -0
  67. data/spec/templates/base_spec.rb +25 -0
  68. data/spec/templates/blackberry_widget_config_spec.rb +94 -0
  69. data/spec/templates/ios_info_spec.rb +68 -0
  70. data/spec/templates/java_checks_spec.rb +59 -0
  71. data/spec/templates/symbian_wrt_info_spec.rb +68 -0
  72. data/spec/templates/webos_appinfo_spec.rb +101 -0
  73. data/spec/typedset_spec.rb +72 -0
  74. metadata +256 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ tmp/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in confetti.gemspec
4
+ gemspec
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
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "confetti/cli"
4
+ Confetti::CLI.start
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'
@@ -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,13 @@
1
+ module Confetti
2
+ class Config
3
+ class Feature
4
+ attr_reader :param_set
5
+
6
+ Param = Class.new
7
+
8
+ def initialize
9
+ @param_set = TypedSet.new Param
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module Confetti
2
+ module Helpers
3
+ def is_file? (filename)
4
+ File.exist? filename
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module Confetti
2
+ module Template
3
+ end
4
+ 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>