confetti 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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>