shenzhen 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/Gemfile +3 -0
- data/Gemfile.lock +31 -0
- data/LICENSE +19 -0
- data/README.md +59 -0
- data/Rakefile +10 -0
- data/bin/ipa +20 -0
- data/lib/shenzhen.rb +6 -0
- data/lib/shenzhen/agvtool.rb +17 -0
- data/lib/shenzhen/commands.rb +7 -0
- data/lib/shenzhen/commands/build.rb +101 -0
- data/lib/shenzhen/commands/distribute.rb +1 -0
- data/lib/shenzhen/plugins/testflight.rb +104 -0
- data/lib/shenzhen/xcodebuild.rb +63 -0
- data/shenzhen.gemspec +27 -0
- metadata +131 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
shenzhen (0.0.1)
|
5
|
+
commander (~> 4.1.2)
|
6
|
+
faraday (~> 0.8.0)
|
7
|
+
faraday_middleware (~> 0.8.7)
|
8
|
+
json (~> 1.7.3)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
commander (4.1.2)
|
14
|
+
highline (~> 1.6.11)
|
15
|
+
faraday (0.8.1)
|
16
|
+
multipart-post (~> 1.1)
|
17
|
+
faraday_middleware (0.8.7)
|
18
|
+
faraday (>= 0.7.4, < 0.9)
|
19
|
+
highline (1.6.15)
|
20
|
+
json (1.7.5)
|
21
|
+
multipart-post (1.1.5)
|
22
|
+
rake (0.9.2.2)
|
23
|
+
rspec (0.6.4)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
rake (~> 0.9.2)
|
30
|
+
rspec (~> 0.6.1)
|
31
|
+
shenzhen!
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012 Mattt Thompson (http://mattt.me/)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Shenzhen
|
2
|
+
**CLI for Building & Distributing iOS Apps (.ipa Files)**
|
3
|
+
|
4
|
+
Create `.ipa` files and then distribute them to TestFlight, all from the command line!
|
5
|
+
|
6
|
+
Less cumbersome than clicking around in Xcode, and less hassle than rolling your own build script--Shenzhen radically improves the process of getting new builds out to testers and enterprises.
|
7
|
+
|
8
|
+
This project is starting with TestFlight, but will move to support other popular distribution methods, such as S3, CloudApp, and /or Dropbox. Suggestions (and pull requests) are very welcome.
|
9
|
+
|
10
|
+
> `shenzhen` is named for [深圳](http://en.wikipedia.org/wiki/Shenzhen), the Chinese city famous for its role as the center of manufacturing for a majority of consumer electronics, including iPhones and iPads. Its [sister project](https://github.com/mattt/cupertino)'s namesake, [Cupertino, CA](http://en.wikipedia.org/wiki/Cupertino,_California), is home to Apple, Inc.'s world headquarters.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
```
|
15
|
+
$ gem install shenzhen
|
16
|
+
```
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Shenzhen adds the `ipa` command to your PATH,
|
21
|
+
|
22
|
+
```
|
23
|
+
$ ipa
|
24
|
+
|
25
|
+
Build and distribute iOS apps (.ipa files)
|
26
|
+
|
27
|
+
Commands:
|
28
|
+
build Create a new .ipa file for your app
|
29
|
+
distribute:testflight Distribute an .ipa file over testflight
|
30
|
+
help Display global or [command] help documentation.
|
31
|
+
|
32
|
+
Aliases:
|
33
|
+
distribute distribute:testflight
|
34
|
+
|
35
|
+
Global Options:
|
36
|
+
-h, --help Display help documentation
|
37
|
+
-v, --version Display version information
|
38
|
+
-t, --trace Display backtrace when an error occurs
|
39
|
+
```
|
40
|
+
|
41
|
+
### Building & Distribution
|
42
|
+
|
43
|
+
```
|
44
|
+
$ cd /path/to/iOS Project/
|
45
|
+
$ ipa build
|
46
|
+
$ ipa distribute
|
47
|
+
```
|
48
|
+
|
49
|
+
## Contact
|
50
|
+
|
51
|
+
Mattt Thompson
|
52
|
+
|
53
|
+
- http://github.com/mattt
|
54
|
+
- http://twitter.com/mattt
|
55
|
+
- m@mattt.me
|
56
|
+
|
57
|
+
## License
|
58
|
+
|
59
|
+
Shenzhen is available under the MIT license. See the LICENSE file for more info.
|
data/Rakefile
ADDED
data/bin/ipa
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'commander/import'
|
4
|
+
|
5
|
+
$:.push File.expand_path("../../lib", __FILE__)
|
6
|
+
require 'shenzhen'
|
7
|
+
|
8
|
+
HighLine.track_eof = false # Fix for built-in Ruby
|
9
|
+
|
10
|
+
program :version, Shenzhen::VERSION
|
11
|
+
program :description, 'Build and distribute iOS apps (.ipa files)'
|
12
|
+
|
13
|
+
program :help, 'Author', 'Mattt Thompson <m@mattt.me>'
|
14
|
+
program :help, 'Website', 'http://mattt.me'
|
15
|
+
program :help_formatter, :compact
|
16
|
+
|
17
|
+
# global_option '--verbose'
|
18
|
+
default_command :help
|
19
|
+
|
20
|
+
require 'shenzhen/commands'
|
data/lib/shenzhen.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Shenzhen::Agvtool
|
2
|
+
class << self
|
3
|
+
def what_version
|
4
|
+
output = `agvtool what-version -terse`
|
5
|
+
output.length > 0 ? output : nil
|
6
|
+
end
|
7
|
+
|
8
|
+
alias :vers :what_version
|
9
|
+
|
10
|
+
def what_marketing_version
|
11
|
+
output = `agvtool what-marketing-version -terse`
|
12
|
+
output.scan(/\=(.+)$/).flatten.first
|
13
|
+
end
|
14
|
+
|
15
|
+
alias :mvers :what_marketing_version
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
command :build do |c|
|
2
|
+
c.syntax = 'ipa build [options] [output]'
|
3
|
+
c.summary = 'Create a new .ipa file for your app'
|
4
|
+
c.description = ''
|
5
|
+
|
6
|
+
c.example 'description', 'ipa release 478 --tag 3.7.2 --scheme MyApp'
|
7
|
+
c.option '-w', '--workspace WORKSPACE', 'Workspace (.xcworkspace) file to use to build app (automatically detected in current directory)'
|
8
|
+
c.option '-p', '--project PROJECT', 'Project (.xcodeproj) file to use to build app (automatically detected in current directory, overridden by --workspace option, if passed)'
|
9
|
+
c.option '-c', '--configuration CONFIGURATION', 'Configuration used to build'
|
10
|
+
c.option '-s', '--scheme SCHEME', 'Scheme used to build app'
|
11
|
+
c.option '-q', '--quiet', 'Silence warning and success messages'
|
12
|
+
|
13
|
+
c.action do |args, options|
|
14
|
+
validate_xcode_version!
|
15
|
+
|
16
|
+
@xcodebuild_info = Shenzhen::XcodeBuild.info
|
17
|
+
|
18
|
+
@workspace = options.workspace
|
19
|
+
@project = options.project
|
20
|
+
@scheme = options.scheme
|
21
|
+
@configuration = options.configuration
|
22
|
+
|
23
|
+
determine_workspace_or_project! unless @workspace || @project
|
24
|
+
|
25
|
+
determine_configuration! unless @configuration
|
26
|
+
say_error "Configuration #{@configuration} not found" and abort unless @xcodebuild_info.build_configurations.include?(@configuration)
|
27
|
+
|
28
|
+
determine_scheme! unless @scheme
|
29
|
+
say_error "Scheme #{@scheme} not found" and abort unless @xcodebuild_info.schemes.include?(@scheme)
|
30
|
+
|
31
|
+
say_warning "Building \"#{@workspace || @project}\" with Scheme \"#{@scheme}\" and Configuration \"#{@configuration}\"\n" unless options.quiet
|
32
|
+
|
33
|
+
log "xcodebuild", (@workspace || @project)
|
34
|
+
|
35
|
+
flags = []
|
36
|
+
flags << "-sdk iphoneos"
|
37
|
+
flags << "-workspace '#{@workspace}'" if @workspace
|
38
|
+
flags << "-project '#{@project}'" if @project
|
39
|
+
flags << "-scheme '#{@scheme}'" if @scheme
|
40
|
+
flags << "-configuration Release"
|
41
|
+
|
42
|
+
ENV['CC'] = nil # Fix for RVM
|
43
|
+
abort unless system "xcodebuild #{flags.join(' ')} clean build 1> /dev/null"
|
44
|
+
|
45
|
+
log "xcrun", "PackageApplication"
|
46
|
+
|
47
|
+
@xcodebuild_settings = Shenzhen::XcodeBuild.settings(flags)
|
48
|
+
|
49
|
+
@app_path = File.join(@xcodebuild_settings['BUILT_PRODUCTS_DIR'], @xcodebuild_settings['PRODUCT_NAME']) + ".app"
|
50
|
+
@dsym_path = @app_path + ".dSYM"
|
51
|
+
@ipa_path = File.join(Dir.pwd, @xcodebuild_settings['PRODUCT_NAME']) + ".ipa"
|
52
|
+
abort unless system %{xcrun -sdk iphoneos PackageApplication -v "#{@app_path}" -o "#{@ipa_path}" --embed "#{@dsym_path}" 1> /dev/null}
|
53
|
+
|
54
|
+
say_ok "#{File.basename(@ipa_path)} successfully built" unless options.quiet
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def validate_xcode_version!
|
60
|
+
version = Shenzhen::XcodeBuild.version
|
61
|
+
say_error "Shenzhen requires Xcode 4 (found #{version}). Please install or switch to the latest Xcode." and abort if version < "4.0.0"
|
62
|
+
end
|
63
|
+
|
64
|
+
def determine_workspace_or_project!
|
65
|
+
workspaces, projects = Dir["*.xcworkspace"], Dir["*.xcodeproj"]
|
66
|
+
|
67
|
+
if workspaces.empty?
|
68
|
+
if projects.empty?
|
69
|
+
say_error "No Xcode projects or workspaces found in current directory" and abort
|
70
|
+
else
|
71
|
+
if projects.length == 1
|
72
|
+
@project = projects.first
|
73
|
+
else
|
74
|
+
@project = choose "Select a project:", *projects
|
75
|
+
end
|
76
|
+
end
|
77
|
+
else
|
78
|
+
if workspaces.length == 1
|
79
|
+
@workspace = workspaces.first
|
80
|
+
else
|
81
|
+
@workspace = choose "Select a workspace:", *workspaces
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def determine_scheme!
|
87
|
+
if @xcodebuild_info.schemes.length == 1
|
88
|
+
@scheme = @xcodebuild_info.schemes.first
|
89
|
+
else
|
90
|
+
@scheme = choose "Select a scheme:", *@xcodebuild_info.schemes
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def determine_configuration!
|
95
|
+
if @xcodebuild_info.build_configurations.length == 1
|
96
|
+
@configuration = @xcodebuild_info.build_configurations.first
|
97
|
+
else
|
98
|
+
@configuration = choose "Select a configuration:", *@xcodebuild_info.build_configurations
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
alias_command :distribute, :'distribute:testflight'
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday_middleware'
|
4
|
+
|
5
|
+
module Shenzhen::Plugins
|
6
|
+
module TestFlight
|
7
|
+
class Client
|
8
|
+
HOSTNAME = 'testflightapp.com'
|
9
|
+
|
10
|
+
def initialize(api_token, team_token)
|
11
|
+
@api_token, @team_token = api_token, team_token
|
12
|
+
@connection = Faraday.new(:url => "http://#{HOSTNAME}") do |builder|
|
13
|
+
builder.request :multipart
|
14
|
+
builder.request :json
|
15
|
+
builder.response :json, :content_type => /\bjson$/
|
16
|
+
builder.use FaradayMiddleware::FollowRedirects
|
17
|
+
builder.adapter :net_http
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def upload_build(ipa, options)
|
22
|
+
options.update({
|
23
|
+
:api_token => @api_token,
|
24
|
+
:team_token => @team_token,
|
25
|
+
:file => Faraday::UploadIO.new(ipa, 'application/octet-stream')
|
26
|
+
})
|
27
|
+
|
28
|
+
@connection.post("/api/builds.json", options).on_complete do |env|
|
29
|
+
yield env[:status], env[:body] if block_given?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
command :'distribute:testflight' do |c|
|
37
|
+
c.syntax = "ipa distribute:testflight [options]"
|
38
|
+
c.summary = "Distribute an .ipa file over testflight"
|
39
|
+
c.description = ""
|
40
|
+
c.option '-f', '--file FILE', ".ipa file for the build"
|
41
|
+
c.option '-t', '--api_token TOKEN', "API Token. Available at https://testflightapp.com/account/#api-token"
|
42
|
+
c.option '-T', '--team_token TOKEN', "Team Token. Available at https://testflightapp.com/dashboard/team/edit/"
|
43
|
+
c.option '-m', '--notes NOTES', "Release notes for the build"
|
44
|
+
c.option '-l', '--lists LISTS', "Comma separated distribution list names which will receive access to the build"
|
45
|
+
c.option '--notify', "Notify permitted teammates to install the build"
|
46
|
+
c.option '--replace', "Replace binary for an existing build if one is found with the same name/bundle version"
|
47
|
+
c.option '-q', '--quiet', "Silence warning and success messages"
|
48
|
+
|
49
|
+
c.action do |args, options|
|
50
|
+
determine_file! unless @file = options.file
|
51
|
+
say_error "Missing or unspecified .ipa file" and abort unless @file and File.exist?(@file)
|
52
|
+
|
53
|
+
determine_api_token! unless @api_token = options.api_token
|
54
|
+
say_error "Missing API Token" and abort unless @api_token
|
55
|
+
|
56
|
+
determine_team_token! unless @team_token = options.team_token
|
57
|
+
|
58
|
+
determine_notes! unless @notes = options.notes
|
59
|
+
say_error "Missing release notes" and abort unless @notes
|
60
|
+
|
61
|
+
parameters = {}
|
62
|
+
parameters[:file] = @file
|
63
|
+
parameters[:notes] = @notes
|
64
|
+
parameters[:notify] = "true" if options.notify
|
65
|
+
parameters[:replace] = "true" if options.replace
|
66
|
+
parameters[:distribution_lists] = options.lists if options.lists
|
67
|
+
|
68
|
+
client = Shenzhen::Plugins::TestFlight::Client.new(@api_token, @team_token)
|
69
|
+
response = client.upload_build(@file, parameters)
|
70
|
+
case response.status
|
71
|
+
when 200...300
|
72
|
+
say_ok "Build successfully uploaded to TestFlight"
|
73
|
+
else
|
74
|
+
say_error "Error uploading to TestFlight: #{response.body}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def determine_api_token!
|
81
|
+
@api_token ||= ask "API Token:"
|
82
|
+
end
|
83
|
+
|
84
|
+
def determine_team_token!
|
85
|
+
@team_token ||= ask "Team Token:"
|
86
|
+
end
|
87
|
+
|
88
|
+
def determine_file!
|
89
|
+
files = Dir['*.ipa']
|
90
|
+
@file ||= case files.length
|
91
|
+
when 0 then nil
|
92
|
+
when 1 then files.first
|
93
|
+
else
|
94
|
+
@file = choose "Select an .ipa File:", *files
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def determine_notes!
|
99
|
+
placeholder = %{What's new in this release: }
|
100
|
+
|
101
|
+
@notes = ask_editor placeholder
|
102
|
+
@notes = nil if @notes == placeholder
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Shenzhen::XcodeBuild
|
4
|
+
class Info < OpenStruct; end
|
5
|
+
|
6
|
+
class Error < StandardError; end
|
7
|
+
class NilOutputError < Error; end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def info
|
11
|
+
output = `xcodebuild -list 2> /dev/null`
|
12
|
+
raise Error.new $1 if /^xcodebuild\: error\: (.+)$/ === output
|
13
|
+
raise NilOutputError unless /\S/ === output
|
14
|
+
|
15
|
+
lines = output.split(/\n/)
|
16
|
+
hash = {}
|
17
|
+
group = nil
|
18
|
+
|
19
|
+
hash[:project] = lines.shift.match(/\"(.+)\"\:/)[1]
|
20
|
+
|
21
|
+
lines.each do |line|
|
22
|
+
if /\:$/ === line
|
23
|
+
group = line.strip[0...-1].downcase.gsub(/\s+/, '_')
|
24
|
+
hash[group] = []
|
25
|
+
next
|
26
|
+
end
|
27
|
+
|
28
|
+
unless group.nil? or /\.$/ === line
|
29
|
+
hash[group] << line.strip
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
hash.each do |group, values|
|
34
|
+
next unless Array === values
|
35
|
+
values.delete("") and values.uniq!
|
36
|
+
end
|
37
|
+
|
38
|
+
Info.new(hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
def settings(flags = [])
|
42
|
+
output = `xcodebuild #{flags.join(' ')} -showBuildSettings 2> /dev/null`
|
43
|
+
raise Error.new $1 if /^xcodebuild\: error\: (.+)$/ === output
|
44
|
+
raise NilOutputError unless /\S/ === output
|
45
|
+
|
46
|
+
lines = output.split(/\n/)
|
47
|
+
lines.shift
|
48
|
+
|
49
|
+
hash = {}
|
50
|
+
lines.each do |line|
|
51
|
+
key, value = line.split(/\=/).collect(&:strip)
|
52
|
+
hash[key] = value
|
53
|
+
end
|
54
|
+
|
55
|
+
hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def version
|
59
|
+
output = `xcodebuild -version`
|
60
|
+
output.scan(/([\d\.?]+)/).flatten.first rescue nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/shenzhen.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "shenzhen"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "shenzhen"
|
7
|
+
s.authors = ["Mattt Thompson"]
|
8
|
+
s.email = "m@mattt.me"
|
9
|
+
s.homepage = "http://github.com/mattt/shenzhen"
|
10
|
+
s.version = Shenzhen::VERSION
|
11
|
+
s.platform = Gem::Platform::RUBY
|
12
|
+
s.summary = "Shenzhen"
|
13
|
+
s.description = "CLI for Building & Distributing iOS Apps (.ipa Files)"
|
14
|
+
|
15
|
+
s.add_development_dependency "rspec", "~> 0.6.1"
|
16
|
+
s.add_development_dependency "rake", "~> 0.9.2"
|
17
|
+
|
18
|
+
s.add_dependency "commander", "~> 4.1.2"
|
19
|
+
s.add_dependency "json", "~> 1.7.3"
|
20
|
+
s.add_dependency "faraday", "~> 0.8.0"
|
21
|
+
s.add_dependency "faraday_middleware", "~> 0.8.7"
|
22
|
+
|
23
|
+
s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shenzhen
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mattt Thompson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-28 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70338229563260 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.6.1
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70338229563260
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70338229562040 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.9.2
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70338229562040
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: commander
|
38
|
+
requirement: &70338229560720 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 4.1.2
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70338229560720
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: json
|
49
|
+
requirement: &70338229557880 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.7.3
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70338229557880
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: faraday
|
60
|
+
requirement: &70338229546680 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.8.0
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70338229546680
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday_middleware
|
71
|
+
requirement: &70338229545900 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.8.7
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70338229545900
|
80
|
+
description: CLI for Building & Distributing iOS Apps (.ipa Files)
|
81
|
+
email: m@mattt.me
|
82
|
+
executables:
|
83
|
+
- ipa
|
84
|
+
extensions: []
|
85
|
+
extra_rdoc_files: []
|
86
|
+
files:
|
87
|
+
- ./Gemfile
|
88
|
+
- ./Gemfile.lock
|
89
|
+
- ./lib/shenzhen/agvtool.rb
|
90
|
+
- ./lib/shenzhen/commands/build.rb
|
91
|
+
- ./lib/shenzhen/commands/distribute.rb
|
92
|
+
- ./lib/shenzhen/commands.rb
|
93
|
+
- ./lib/shenzhen/plugins/testflight.rb
|
94
|
+
- ./lib/shenzhen/xcodebuild.rb
|
95
|
+
- ./lib/shenzhen.rb
|
96
|
+
- ./LICENSE
|
97
|
+
- ./Rakefile
|
98
|
+
- ./README.md
|
99
|
+
- ./shenzhen.gemspec
|
100
|
+
- bin/ipa
|
101
|
+
homepage: http://github.com/mattt/shenzhen
|
102
|
+
licenses: []
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
segments:
|
114
|
+
- 0
|
115
|
+
hash: 522475160615829235
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
segments:
|
123
|
+
- 0
|
124
|
+
hash: 522475160615829235
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 1.8.15
|
128
|
+
signing_key:
|
129
|
+
specification_version: 3
|
130
|
+
summary: Shenzhen
|
131
|
+
test_files: []
|