fanta 0.0.1

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 ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.8.7
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # 0.0.7 (17 Apr 2011)
2
+ TestFlight task now more closely mimics TestFlight API. See README for new format
3
+
4
+ # 0.0.6 (16 Apr 2011)
5
+ Build now defaults to building the first target in the application. This can be overridden by setting :target
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in wox.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # The Wizard of Xcode
2
+
3
+ wox is a ruby gem that adds useful rake tasks in order to have happier iOS devs.
4
+
5
+ ## Install
6
+
7
+ First set up bundler in your xcode app directory (unless you already have!)
8
+
9
+ $ cd ~/code/angry_turds
10
+ $ gem install bundler
11
+ $ bundle init
12
+
13
+ Then edit your Gemfile to look something like this:
14
+
15
+ # Gemfile
16
+ source :rubygems
17
+ gem "wox"
18
+
19
+ Then run the bundle command:
20
+
21
+ $ bundle
22
+
23
+ Now, create a Rakefile (unless you already have one!):
24
+
25
+ # Rakefile
26
+ include Rake::DSL
27
+ require 'bundler'
28
+ Bundler.require
29
+
30
+ Wox::Tasks.create :info_plist => 'Resources/Info.plist' do
31
+ build :debug, :configuration => 'Debug'
32
+ end
33
+
34
+ Now run rake -T to show you the available rake commands and you should see something like this:
35
+
36
+ $ rake -T
37
+ rake build:debug # Build angry_turds 0.1 with Debug configuration
38
+ rake info:configurations # List available configurations
39
+ rake info:sdks # List available sdks
40
+ $ rake build:debug
41
+ Building angry_turds 0.3 configuration:Debug
42
+ Success. Results in build/build-Debug.log
43
+
44
+ If you get an error you might need to check the path of the info plist file. We use that to get the version number of the app.
45
+
46
+ ## Moar stuff!
47
+
48
+ Ok so there's a few more things you can do, like creating ipa files and publishing to TestFlight. That looks like this:
49
+
50
+ # Rakefile
51
+ include Rake::DSL
52
+ require 'bundler'
53
+ Bundler.require
54
+
55
+ Wox::Tasks.create :info_plist => 'Resources/Info.plist', :sdk => 'iphoneos', :configuration => 'Release' do
56
+ build :debug, :configuration => 'Debug'
57
+
58
+ build :release, :developer_certificate => 'iPhone Developer: Dangerous Dave (9GZ84DL0DZ)' do
59
+ ipa :app_store, :provisioning_profile => 'App Store'
60
+ ipa :adhoc, :provisioning_profile => 'Team Provisioning Profile' do
61
+ testflight :publish, :api_token => 'nphsZ6nVXMl0brDEsevLY0wRfU6iP0NLaQH3nqoh8jG',
62
+ :team_token => 'Qfom2HnGGJnXrUVnOKAxKAmpNO3wdQ9panhtqcA',
63
+ :notes => proc { File.read("CHANGELOG") },
64
+ :distribution_lists => %w[Internal QA],
65
+ :notify => true
66
+
67
+ end
68
+ end
69
+ end
70
+
71
+ There's a few things to notice here. Some tasks need to be nested inside other tasks. This allows them to share environment variables. For example :configuration => 'Release' is on the outer most scope at the top there. That sets the default for all the tasks inside. Any task can override the default like the first build :debug task does. The build :release task sets a developer certificate here which is then shared by the two inner ipa tasks.
72
+
73
+ rake -T again:
74
+
75
+ $ rake -T
76
+ rake build:debug # Build angry_turds 0.1 with Debug configuration
77
+ rake build:release # Build angry_turds 0.1 with Release configuration
78
+ rake info:configurations # List available configurations
79
+ rake info:sdks # List available sdks
80
+ rake ipa:adhoc # Creates build/angry_turds-0.1-release-adhoc.ipa
81
+ rake ipa:app_store # Creates build/angry_turds-0.1-release-app_store.ipa
82
+ rake testflight:publish # Publishes build/angry_turds-0.1-release-adhoc.ipa to testflight
83
+
84
+ You'll need to sign up to [TestFlight](http://testflightapp.com) to get your API key and team token which you can plug in here.
85
+
86
+ Also check your development certificate and provisioning profile from inside Xcode.
87
+
88
+ ## Available options
89
+
90
+ The following options can be set at any level and will be inherited by child tasks.
91
+
92
+ * :info_plist Default: 'Resources/Info.plist'
93
+ * :version Default: 'CFBundleVersion' from info plist file
94
+ * :target Default: first target in xcode
95
+ * :sdk Default: 'iphoneos'
96
+ * :build_dir Default: 'build'
97
+ * :configuration Default: 'Release'
98
+ * :project_name Default: project name from xcode
99
+ * :app_file Default: project_name
100
+ * :ipa_name Default: 'project_name-version-configuration-ipa_name'
101
+
102
+ ## Wrapping up
103
+
104
+ This is very much a WIP! So please log any bugs or feedback you might have and feel free to fork and go nuts!
105
+
106
+
107
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/fanta.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fanta/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "fanta"
7
+ s.version = Fanta::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Croath Liu"]
10
+ s.email = ["Croath.Liu@gmail.com"]
11
+ s.homepage = "https://github.com/croath"
12
+ s.summary = %q{The Wizard of Xcode}
13
+ s.description = %q{use Fanta to test/build your iOS application}
14
+
15
+ s.rubyforge_project = ""
16
+
17
+ s.add_dependency "thor"
18
+ s.add_dependency "plist"
19
+ s.add_dependency "rubyzip"
20
+
21
+ s.add_development_dependency "rspec"
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,80 @@
1
+ require 'plist'
2
+
3
+ module Fanta
4
+ module Environment
5
+ attr_reader :environment
6
+ def initialize environment
7
+ @environment = environment
8
+ end
9
+ end
10
+
11
+ class BuildEnvironment
12
+ attr_reader :info_plist, :build_dir, :default_sdk
13
+
14
+ def initialize options
15
+ @options = options
16
+
17
+ options[:info_plist] ||= 'Resources/Info.plist'
18
+ options[:version] ||= Plist::parse_xml(options[:info_plist])['CFBundleVersion']
19
+ options[:project_name] ||= xcodebuild_list.first.scan(/project\s\"([^\"]+)/i).flatten.first
20
+ options[:full_name] ||= "#{self[:project_name]} #{self[:version]}"
21
+ options[:build_dir] ||= 'build'
22
+ options[:sdk] ||= 'iphoneos'
23
+ options[:configuration] ||= 'Release'
24
+ options[:target] ||= targets.first
25
+ options[:app_file] ||= self[:project_name]
26
+ options[:target_or_scheme] ||= 'target'
27
+
28
+ if options[:ipa_name]
29
+ options[:ipa_file] ||= File.join self[:build_dir],
30
+ [self[:project_name], self[:version], self[:configuration], self[:ipa_name]].join("-") + ".ipa"
31
+ options[:dsym_file] ||= File.join self[:build_dir],
32
+ [self[:project_name], self[:version], self[:configuration], self[:ipa_name]].join("-") + ".dSYM.zip"
33
+ end
34
+ end
35
+
36
+ def apply options, &block
37
+ yield BuildEnvironment.new @options.merge(options)
38
+ end
39
+
40
+ def version
41
+ self[:version]
42
+ end
43
+
44
+ def sdks
45
+ @sdks ||= `xcodebuild -showsdks`.scan(/-sdk (.*?$)/m).flatten
46
+ end
47
+
48
+ def configurations
49
+ @configurations ||= begin
50
+ start_line = xcodebuild_list.find_index{ |l| l =~ /configurations/i } + 1
51
+ end_line = xcodebuild_list.find_index{ |l| l =~ /if no/i } - 1
52
+ xcodebuild_list.slice start_line...end_line
53
+ end
54
+ end
55
+
56
+ def targets
57
+ @targets ||= begin
58
+ start_line = xcodebuild_list.find_index{ |l| l =~ /targets/i } + 1
59
+ end_line = xcodebuild_list.find_index{ |l| l =~ /configurations/i } - 1
60
+ xcodebuild_list.slice(start_line...end_line).map{|l| l.gsub('(Active)','').strip }
61
+ end
62
+ end
63
+
64
+ def [](name)
65
+ fail "You need to specify :#{name} in Rakefile" unless @options[name]
66
+ @options[name].respond_to?(:call) ? @options[name].call : @options[name]
67
+ end
68
+
69
+ def has_entry? name
70
+ @options[name]
71
+ end
72
+
73
+ private
74
+
75
+ def xcodebuild_list
76
+ @xcodebuild_list ||= `xcodebuild -list`.lines.map{|l| l.strip }.to_a
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,15 @@
1
+ module Fanta
2
+ class Builder < Task
3
+ include Environment
4
+ # def initialize(environment); super end
5
+
6
+ def build
7
+ configuration = environment[:configuration]
8
+ puts "Building #{environment[:full_name]} configuration:#{configuration}"
9
+
10
+ log_file = File.join environment[:build_dir], "build-#{configuration}.log"
11
+
12
+ run_command "xcodebuild -#{environment[:target_or_scheme]} '#{environment[:target]}' -configuration #{configuration} BUILD_DIR=#{environment[:build_dir]} clean build", :results => log_file
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module Fanta
2
+ module NumberHelper
3
+ def plural count, singular, plural
4
+ count == 1 ? singular : plural
5
+ end
6
+
7
+ def bytes_to_human_size bytes, precision = 1
8
+ kb = 1024
9
+ mb = 1024 * kb
10
+ gb = 1024 * mb
11
+ case
12
+ when bytes < kb; "%d #{plural(bytes, 'byte', 'bytes')}" % bytes
13
+ when bytes < mb; "%.#{precision}f #{plural((bytes / kb), 'kilobyte', 'kilobytes')}" % (bytes / kb)
14
+ when bytes < gb; "%.#{precision}f #{plural((bytes / mb), 'megabyte', 'megabytes')}" % (bytes / mb)
15
+ when bytes >= gb; "%.#{precision}f #{plural((bytes / gb), 'gigabyte', 'gigabytes')}" % (bytes / gb)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module Fanta
2
+ class Packager < Task
3
+ include Environment
4
+
5
+ def package
6
+ configuration, sdk, ipa_file, build_dir = environment[:configuration], environment[:sdk], environment[:ipa_file], environment[:build_dir]
7
+
8
+ app_file = File.join build_dir, "#{configuration}-#{sdk}", environment[:app_file]
9
+ app_file += ".app" unless app_file =~ /\.app^/
10
+
11
+ fail "Couldn't find #{app_file}" unless File.exists? app_file
12
+
13
+ provisioning_profile_file = find_matching_mobile_provision environment[:provisioning_profile]
14
+ fail "Unable to find matching provisioning profile for '#{environment[:provisioning_profile]}'" if provisioning_profile_file.empty?
15
+
16
+ puts "Creating #{ipa_file}"
17
+ log_file = File.join build_dir, "ipa.log"
18
+ run_command "xcrun -sdk #{sdk} PackageApplication -v '#{app_file}' -o '#{File.expand_path ipa_file}' --sign '#{environment[:developer_certificate]}' --embed '#{provisioning_profile_file}'", :results => log_file
19
+ end
20
+
21
+ def find_matching_mobile_provision match_text
22
+ `grep -rl '#{match_text}' '#{ENV['HOME']}/Library/MobileDevice/Provisioning\ Profiles/'`.strip
23
+ end
24
+
25
+ end
26
+ end
data/lib/fanta/task.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Fanta
2
+ class Task
3
+ def run_command text, options
4
+ result = `#{text}`
5
+
6
+ File.open(options[:results], "w") {|f| f.write result }
7
+
8
+ if $?.to_i == 0
9
+ puts "Success. Results in #{options[:results]}"
10
+ puts
11
+ else
12
+ fail exec "cat #{options[:results]}"
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,82 @@
1
+ require 'thor'
2
+
3
+ module Fanta
4
+ module TasksScope
5
+ attr_reader :environment, :parent_task
6
+ def initialize environment, parent_task = nil
7
+ @environment = environment
8
+ @parent_task = parent_task
9
+ end
10
+ end
11
+
12
+ class Tasks
13
+ def self.create options = {}, &block
14
+ tasks = self.new(BuildEnvironment.new(options))
15
+ tasks.default_tasks
16
+ tasks.instance_eval &block if block_given?
17
+ end
18
+
19
+ include TasksScope
20
+
21
+ def default_tasks
22
+ namespace :info do
23
+ desc "List available sdks"
24
+ task :sdks do
25
+ puts environment.sdks.join("\n")
26
+ end
27
+
28
+ desc "List available configurations"
29
+ task :configurations do
30
+ puts environment.configurations.join("\n")
31
+ end
32
+
33
+ desc "List project targets"
34
+ task :targets do
35
+ puts environment.targets.join("\n")
36
+ end
37
+ end
38
+ end
39
+
40
+ def build name, options, &block
41
+ environment.apply options do |e|
42
+ t = nil
43
+ namespace :build do
44
+ desc "Build #{e[:full_name]} with #{e[:configuration]} configuration"
45
+ t = task(name) { Builder.new(e).build }
46
+ end
47
+ tasks = BuildTasks.new(e, t)
48
+ tasks.instance_eval &block if block_given?
49
+ end
50
+ end
51
+ end
52
+
53
+ class BuildTasks
54
+ include TasksScope
55
+
56
+ def ipa name, options, &block
57
+ environment.apply options.merge({:ipa_name => name}) do |e|
58
+ t = nil
59
+ namespace :ipa do
60
+ desc "Creates #{e[:ipa_file]}"
61
+ t = task(name => parent_task) { Packager.new(e).package }
62
+ end
63
+
64
+ tasks = IpaTasks.new(e, t)
65
+ tasks.instance_eval &block if block_given?
66
+ end
67
+ end
68
+ end
69
+
70
+ class IpaTasks
71
+ include TasksScope
72
+
73
+ def testflight name, options
74
+ environment.apply options do |e|
75
+ namespace :testflight do
76
+ desc "Publishes #{e[:ipa_file]} to testflight"
77
+ task(name => parent_task) { TestFlight.new(e).publish }
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,3 @@
1
+ module Fanta
2
+ VERSION = "0.0.1"
3
+ end
data/lib/fanta.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'fanta/build_environment'
2
+ require 'fanta/task'
3
+ require 'fanta/builder'
4
+ require 'fanta/packager'
5
+ require 'fanta/test_flight'
6
+ require 'fanta/tasks'
7
+
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fanta
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Croath Liu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: plist
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rubyzip
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: use Fanta to test/build your iOS application
79
+ email:
80
+ - Croath.Liu@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .rvmrc
87
+ - CHANGELOG.md
88
+ - Gemfile
89
+ - README.md
90
+ - Rakefile
91
+ - fanta.gemspec
92
+ - lib/fanta.rb
93
+ - lib/fanta/build_environment.rb
94
+ - lib/fanta/builder.rb
95
+ - lib/fanta/helpers/number_helper.rb
96
+ - lib/fanta/packager.rb
97
+ - lib/fanta/task.rb
98
+ - lib/fanta/tasks.rb
99
+ - lib/fanta/version.rb
100
+ homepage: https://github.com/croath
101
+ licenses: []
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project: ''
120
+ rubygems_version: 1.8.25
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: The Wizard of Xcode
124
+ test_files: []