joe_jenkins 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+
2
+ class JJDebugger
3
+
4
+
5
+ def self.prettyLog(m="",count=%x[tput cols])
6
+ if(m.length > 0)
7
+ c = (count.to_i - (m.length+10))/2
8
+ c = 0 if(c < 0)
9
+ print ('*'*c)+(' '*5)+m+(' '*5)+('*'*c)+"\n"
10
+ else
11
+ print '*'*count.to_i+"\n"
12
+ end
13
+ end
14
+
15
+ def self.log(m)
16
+ print "\n"
17
+ 1.times do self.prettyLog end
18
+ self.prettyLog(m.to_s)
19
+ 1.times do self.prettyLog end
20
+ print "\n"
21
+ end
22
+
23
+
24
+ end
@@ -0,0 +1,186 @@
1
+ require 'helpers/jj_debug'
2
+
3
+ class JJXcode
4
+ attr_accessor :projectName, :projectDirectory
5
+ attr_accessor :bundleIdentifier
6
+ attr_accessor :signer
7
+ attr_accessor :profile
8
+ attr_accessor :macroFlags
9
+
10
+ attr_accessor :verbose
11
+
12
+ attr_accessor :targets
13
+ attr_accessor :configurations
14
+ attr_accessor :schemes
15
+
16
+ attr_accessor :profileDirectory
17
+
18
+ def initialize(verbose=false)
19
+ @verbose = verbose
20
+ system "clear"
21
+ @profileDirectory = "~/Library/MobileDevice/Provisioning\ Profiles/"
22
+ @projectDirectory = Dir.pwd
23
+ end
24
+
25
+ def methods()
26
+ var = Array.new
27
+ var.push "getInstalledProfiles"
28
+ var.push "listProfiles"
29
+ var.push "getTargets"
30
+ var.push "doBuild"
31
+ var.push "reSignApp"
32
+ var.push "packageApp"
33
+
34
+ var
35
+ end
36
+
37
+ def log(msg)
38
+ JJDebugger.log(msg) if @verbose
39
+ end
40
+
41
+ def getInstalledProfiles
42
+ profile_list = Array.new
43
+ Dir.glob(File.expand_path(@profileDirectory)+"/*.mobileprovision").each do |profile|
44
+ profile_list.push(profile.split("/").last.split(".").first)
45
+ end
46
+
47
+ profile_list
48
+ end
49
+
50
+ def listProfiles
51
+ log "Listing Profiles in #{File.expand_path(@profileDirectory)}"
52
+ getInstalledProfiles.each do |p|
53
+ print "Profile: #{p}\n"
54
+ end
55
+ end
56
+
57
+ def getTargets()
58
+ d = getProjectInfo()
59
+ @targets = d[:targets]
60
+ @configurations = d[:configurations]
61
+ @schemes = d[:schemes]
62
+ @targets
63
+ end
64
+
65
+ def buildDir(configuration="")
66
+ return "#{@projectDirectory}/build/#{configuration}-iphoneos/"
67
+ end
68
+
69
+ def binaryLocation(configuration="")
70
+ log buildDir(configuration)
71
+ return Dir.glob("#{buildDir(configuration)}*.app").first
72
+ end
73
+
74
+ # Do an 'xcodebuild -configuration -xcconfig' with given params
75
+ # @return The path to the .app file
76
+
77
+ def doBuild(configuration="Debug", config="")
78
+ if(config == "")
79
+ config = createXCConfig()
80
+ end
81
+ output = doXcodeCall("-configuration #{configuration}"+(config.length>0 ? " -xcconfig #{config}" : ""))
82
+ if(output.include?"BUILD SUCCEEDED")
83
+ binaryLoc = binaryLocation(configuration)
84
+ log "Build Output Here: #{binaryLoc}"
85
+ return binaryLoc
86
+ else
87
+ log "BUILD FAILED"
88
+ return nil
89
+ end
90
+ end
91
+
92
+
93
+ def reSignApp(binaryLocation,signer)
94
+ config = File.dirname(binaryLocation).split("/").last.split('-').first
95
+ entitlementsDir = Dir.glob("#{@projectDirectory}/build/*.build").first
96
+ entitlements = Dir.glob(Dir.glob(entitlementsDir+"/#{config}-iphoneos/*.build").first+"/*.xcent").first
97
+ %x[codesign -f -s "iPhone Distribution: #{signer}" #{File.expand_path(binaryLocation)} --entitlements #{File.expand_path(entitlements)}]
98
+ end
99
+
100
+ #output dir defaults to wherever the script is called from
101
+
102
+ def packageApp(binaryLocation, profile, outputLocation=File.expand_path("./"))
103
+ log "Packaging Application to IPA: #{binaryLocation}"
104
+ appName = binaryLocation.split("/").last.split(".").first
105
+ p_name = profile.split(".").first
106
+ if(!getInstalledProfiles.include?p_name)
107
+ raise ArgumentError, "Profile Not found on machine", p_name
108
+ end
109
+ profileLoc = @profileDirectory+p_name
110
+ ipaLoc = outputLocation+"/"+appName+".ipa"
111
+ log %x[xcrun -sdk iphoneos PackageApplication #{"-v" if @verbose} "#{binaryLocation}" -o "#{ipaLoc}" --embed "#{profileLoc}.mobileprovision"]
112
+ log "IPA OutputDir: #{ipaLoc}"
113
+ ipaLoc if(File.exists?ipaLoc)
114
+ end
115
+
116
+ private
117
+ def doXcodeCall(call="")
118
+ log("Doing Xcode call \"#{call}\"")
119
+ output = %x[cd \"#{@projectDirectory}\";xcodebuild #{call}]
120
+ log output
121
+ return output
122
+ end
123
+
124
+ def createXCConfig()
125
+ if(!@profile || !@bundleIdentifier || !@signer)
126
+ print "Error: You must specify profile, signer, and bundleIdentifier to create a valid scheme\n"
127
+ return nil
128
+ end
129
+
130
+ profile_path = File.expand_path(@profileDirectory)+"/#{@profile}.mobileprovision"
131
+ file = File.open(profile_path, "r")
132
+ fdata = file.read
133
+ file.close()
134
+ fdata[0, fdata.index('<?xml')] = ''
135
+
136
+ plist_end = fdata.index('</plist>') + 8
137
+ fdata[plist_end, fdata.length - plist_end] = ''
138
+
139
+ profileData = Plist::parse_xml(fdata)
140
+
141
+ profile_uuid = profileData['UUID']
142
+
143
+ log "Creating scheme:\nProfile: #{@profile}\nSigner: #{@signer}\nBundleIdentifier: #{@bundleIdentifier}"
144
+ data = "CODE_SIGN_IDENTITY = iPhone Distribution: #{@signer};\n"
145
+ data += "RUN_CLANG_STATIC_ANALYZER = NO;\n"
146
+ data += "PROVISIONING_PROFILE = #{profile_uuid};\n"
147
+ data += "CustomBundleID = #{@bundleIdentifier};\n"
148
+ data += "GCC_PREPROCESSOR_DEFINITIONS = #{@macroFlags};\n"
149
+
150
+ xc_s = File.new("config.xcconfig", "w")
151
+ xc_s.write(data)
152
+ xc_s.close
153
+ return "config.xcconfig"
154
+ end
155
+
156
+ def getProjectInfo()
157
+ doXcodeCall("-list")
158
+ info = Hash.new
159
+ info[:targets] = Array.new
160
+ info[:configurations] = Array.new
161
+ info[:schemes] = Array.new
162
+
163
+ t,c,s = false
164
+ data.split("\n").each do |line|
165
+ line.gsub!(' ','')
166
+
167
+ if(line == "Targets:")
168
+ t=true
169
+ elsif(line == "BuildConfigurations:")
170
+ c=true
171
+ elsif(line == "Schemes:")
172
+ s=true
173
+ elsif (t or c or s)
174
+ if(line.length > 0)
175
+ info[:targets].push line if(t)
176
+ info[:configurations].push line if(c)
177
+ info[:schemes].push line if(s)
178
+ else
179
+ t=c=s=false
180
+ end
181
+ end
182
+ end
183
+ return info
184
+ end
185
+
186
+ end
@@ -0,0 +1,48 @@
1
+
2
+ require 'helpers/jj_xcode'
3
+
4
+ require 'zip/zip'
5
+ require 'plist'
6
+ require 'json'
7
+
8
+ class JoeJenkins
9
+
10
+ attr_accessor :config
11
+
12
+ def initialize(verbose=false)
13
+ @xcode = JJXcode.new(verbose)
14
+ end
15
+
16
+ def doBuildWithConfig(config)
17
+ @config = config
18
+
19
+ @xcode.profile = config[:profile]
20
+ @xcode.signer = config[:signer]
21
+ @xcode.bundleIdentifier = config[:bundleID]
22
+
23
+ appOutputLocation = @xcode.doBuild(config[:configuration])
24
+
25
+ print "Write Config to #{@xcode.buildDir(@config[:configuration])+"/config.txt"}\n"
26
+ File.open(@xcode.buildDir(@config[:configuration])+"/config.txt", "w") do |f|
27
+ f.puts @config.to_json
28
+ end
29
+ # print "This is the output #{appOutputLocation}\n"
30
+ return appOutputLocation
31
+ end
32
+
33
+
34
+ def postBuild(bc_url)
35
+
36
+ dir_to_zip = @xcode.buildDir(@config[:configuration])
37
+ output_path = Dir.pwd+"/bundle.tgz"
38
+ output = %x[cd "#{dir_to_zip}";tar -cvzf "#{output_path}" ./]
39
+
40
+ res = RestClient.post bc_url, :app => File.new(output_path)
41
+ print "\nPost complete #{res.to_str}\n<br/>"
42
+ end
43
+
44
+ def createDistributionPlist
45
+
46
+ end
47
+
48
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: joe_jenkins
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Joseph Ridenour
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-06-22 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Simple builder classes for creating markup.
22
+ email: jridenour@mercury.io
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/helpers/jj_debug.rb
31
+ - lib/helpers/jj_xcode.rb
32
+ - lib/joe_jenkins.rb
33
+ has_rdoc: true
34
+ homepage: http://mercury.io
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --title
40
+ - Xcode Helper for helping xcode
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.3.6
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: JoeJenkins gem is a helper for all processes of building and deploying mobile
64
+ test_files: []
65
+