joe_jenkins 1.0.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.
- data/lib/helpers/jj_debug.rb +24 -0
- data/lib/helpers/jj_xcode.rb +186 -0
- data/lib/joe_jenkins.rb +48 -0
- metadata +65 -0
@@ -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
|
data/lib/joe_jenkins.rb
ADDED
@@ -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
|
+
|