deploygate 0.0.6 → 0.1.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.
- checksums.yaml +13 -5
- data/.gitignore +4 -0
- data/.travis.yml +4 -4
- data/README.md +3 -3
- data/lib/deploygate/android/gradle_deploy.rb +95 -0
- data/lib/deploygate/android/gradle_plugin_installer.rb +101 -0
- data/lib/deploygate/android/gradle_project.rb +14 -0
- data/lib/deploygate/commands/deploy/build.rb +15 -154
- data/lib/deploygate/{build.rb → project.rb} +3 -3
- data/lib/deploygate/version.rb +1 -1
- data/lib/deploygate/xcode/analyze.rb +116 -0
- data/lib/deploygate/xcode/export.rb +281 -0
- data/lib/deploygate/{builds → xcode}/ios.rb +13 -5
- data/lib/deploygate/xcode/member_center.rb +52 -0
- data/lib/deploygate/xcode/member_centers/app.rb +35 -0
- data/lib/deploygate/xcode/member_centers/provisioning_profile.rb +99 -0
- data/lib/deploygate.rb +14 -5
- data/spec/deploygate/project_spec.rb +39 -0
- data/spec/deploygate/xcode/analyze_spec.rb +3 -0
- data/spec/deploygate/{builds/ios → xcode}/export_spec.rb +21 -21
- data/spec/deploygate/{builds → xcode}/ios_spec.rb +12 -12
- data/spec/deploygate/xcode/member_center_spec.rb +21 -0
- data/spec/deploygate/xcode/member_centers/app_spec.rb +60 -0
- data/spec/deploygate/xcode/member_centers/provisioning_profile_spec.rb +3 -0
- metadata +70 -66
- data/lib/deploygate/builds/ios/analyze.rb +0 -111
- data/lib/deploygate/builds/ios/export.rb +0 -188
- data/lib/deploygate/builds/ios/set_profile.rb +0 -128
- data/spec/deploygate/build_spec.rb +0 -37
- data/spec/deploygate/builds/ios/analyze_spec.rb +0 -3
- data/spec/deploygate/builds/ios/set_profile_spec.rb +0 -3
@@ -0,0 +1,281 @@
|
|
1
|
+
module DeployGate
|
2
|
+
module Xcode
|
3
|
+
class Export
|
4
|
+
AD_HOC = 'ad-hoc'
|
5
|
+
ENTERPRISE = 'enterprise'
|
6
|
+
SUPPORT_EXPORT_METHOD = [AD_HOC, ENTERPRISE]
|
7
|
+
PROFILE_EXTNAME = '.mobileprovision'
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# @param [String] bundle_identifier
|
12
|
+
# @param [String] uuid
|
13
|
+
# @return [String]
|
14
|
+
def provisioning_profile(bundle_identifier, uuid = nil)
|
15
|
+
data = DeployGate::Xcode::Export.find_local_data(bundle_identifier, uuid)
|
16
|
+
profiles = data[:profiles]
|
17
|
+
teams = data[:teams]
|
18
|
+
|
19
|
+
target_provisioning_profile = nil
|
20
|
+
if teams.empty?
|
21
|
+
target_provisioning_profile = create_provisioning(bundle_identifier, uuid)
|
22
|
+
elsif teams.count == 1
|
23
|
+
target_provisioning_profile = select_profile(profiles[teams.keys.first])
|
24
|
+
elsif teams.count >= 2
|
25
|
+
target_provisioning_profile = select_teams(teams, profiles)
|
26
|
+
end
|
27
|
+
|
28
|
+
target_provisioning_profile
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [String] bundle_identifier
|
32
|
+
# @param [String] uuid
|
33
|
+
# @return [Hash]
|
34
|
+
def find_local_data(bundle_identifier, uuid = nil)
|
35
|
+
result_profiles = {}
|
36
|
+
teams = {}
|
37
|
+
profile_paths = load_profile_paths
|
38
|
+
profiles = profile_paths.map{|p| profile_to_plist(p)}
|
39
|
+
profiles.reject! {|profile| profile['UUID'] != uuid} unless uuid.nil?
|
40
|
+
|
41
|
+
profiles.each do |profile|
|
42
|
+
entities = profile['Entitlements']
|
43
|
+
unless entities['get-task-allow']
|
44
|
+
team = entities['com.apple.developer.team-identifier']
|
45
|
+
application_id = entities['application-identifier']
|
46
|
+
application_id.slice!(/^#{team}\./)
|
47
|
+
application_id = '.' + application_id if application_id == '*'
|
48
|
+
if bundle_identifier.match(application_id) &&
|
49
|
+
DateTime.now < profile['ExpirationDate'] &&
|
50
|
+
installed_certificate?(profile['Path'])
|
51
|
+
|
52
|
+
teams[team] = profile['TeamName'] if teams[team].nil?
|
53
|
+
result_profiles[team] = [] if result_profiles[team].nil?
|
54
|
+
result_profiles[team].push(profile['Path'])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
{
|
60
|
+
:teams => teams,
|
61
|
+
:profiles => result_profiles
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
# @param [String] profile_path
|
66
|
+
# @return [Boolean]
|
67
|
+
def installed_certificate?(profile_path)
|
68
|
+
profile = profile_to_plist(profile_path)
|
69
|
+
certs = profile['DeveloperCertificates'].map do |cert|
|
70
|
+
certificate_str = cert.read
|
71
|
+
certificate = OpenSSL::X509::Certificate.new certificate_str
|
72
|
+
id = OpenSSL::Digest::SHA1.new(certificate.to_der).to_s.upcase!
|
73
|
+
installed_distribution_certificate_ids.include?(id)
|
74
|
+
end
|
75
|
+
certs.include?(true)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [Array]
|
79
|
+
def installed_distribution_certificate_ids
|
80
|
+
certificates = installed_certificates()
|
81
|
+
ids = []
|
82
|
+
certificates.each do |current|
|
83
|
+
next unless current.match(/iPhone Distribution:/)
|
84
|
+
begin
|
85
|
+
(ids << current.match(/.*\) (.*) \".*/)[1])
|
86
|
+
rescue
|
87
|
+
# the last line does not match
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
ids
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [Array]
|
95
|
+
def installed_distribution_conflicting_certificates
|
96
|
+
certificates = installed_certificates()
|
97
|
+
names = []
|
98
|
+
certificates.each do |current|
|
99
|
+
begin
|
100
|
+
names << current.match(/(iPhone Distribution:.*)/)[1]
|
101
|
+
rescue
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
conflicting_names = names.select{|e| names.index(e) != names.rindex(e)}.uniq
|
106
|
+
conflicting_certificates = []
|
107
|
+
certificates.each do |current|
|
108
|
+
begin
|
109
|
+
name = current.match(/(iPhone Distribution:.*)/)[1]
|
110
|
+
next unless conflicting_names.include?(name)
|
111
|
+
conflicting_certificates << current
|
112
|
+
rescue
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
conflicting_certificates
|
117
|
+
end
|
118
|
+
|
119
|
+
# @return [Array]
|
120
|
+
def installed_certificates
|
121
|
+
available = `security find-identity -v -p codesigning`
|
122
|
+
certificates = []
|
123
|
+
available.split("\n").each do |current|
|
124
|
+
next if current.include? "REVOKED"
|
125
|
+
certificates << current
|
126
|
+
end
|
127
|
+
|
128
|
+
certificates
|
129
|
+
end
|
130
|
+
|
131
|
+
# @param [Array] profile_paths
|
132
|
+
# @return [String]
|
133
|
+
def select_profile(profile_paths)
|
134
|
+
select = nil
|
135
|
+
|
136
|
+
profile_paths.each do |path|
|
137
|
+
select = path if adhoc?(path) && select.nil?
|
138
|
+
select = path if inhouse?(path)
|
139
|
+
end
|
140
|
+
select
|
141
|
+
end
|
142
|
+
|
143
|
+
# @param [String] profile_path
|
144
|
+
# @return [String]
|
145
|
+
def codesigning_identity(profile_path)
|
146
|
+
profile = profile_to_plist(profile_path)
|
147
|
+
identity = nil
|
148
|
+
|
149
|
+
profile['DeveloperCertificates'].each do |cert|
|
150
|
+
certificate_str = cert.read
|
151
|
+
certificate = OpenSSL::X509::Certificate.new certificate_str
|
152
|
+
id = OpenSSL::Digest::SHA1.new(certificate.to_der).to_s.upcase!
|
153
|
+
|
154
|
+
available = `security find-identity -v -p codesigning`
|
155
|
+
available.split("\n").each do |current|
|
156
|
+
next if current.include? "REVOKED"
|
157
|
+
begin
|
158
|
+
search = current.match(/.*\) (.*) \"(.*)\"/)
|
159
|
+
identity = search[2] if id == search[1]
|
160
|
+
rescue
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
identity
|
166
|
+
end
|
167
|
+
|
168
|
+
# @param [String] profile_path
|
169
|
+
# @return [String]
|
170
|
+
def method(profile_path)
|
171
|
+
adhoc?(profile_path) ? AD_HOC : ENTERPRISE
|
172
|
+
end
|
173
|
+
|
174
|
+
# @param [String] profile_path
|
175
|
+
# @return [Boolean]
|
176
|
+
def adhoc?(profile_path)
|
177
|
+
profile = profile_to_plist(profile_path)
|
178
|
+
!profile['Entitlements']['get-task-allow'] && profile['ProvisionsAllDevices'].nil?
|
179
|
+
end
|
180
|
+
|
181
|
+
# @param [String] profile_path
|
182
|
+
# @return [Boolean]
|
183
|
+
def inhouse?(profile_path)
|
184
|
+
profile = profile_to_plist(profile_path)
|
185
|
+
!profile['Entitlements']['get-task-allow'] && !profile['ProvisionsAllDevices'].nil?
|
186
|
+
end
|
187
|
+
|
188
|
+
def load_profile_paths
|
189
|
+
profiles_path = File.expand_path("~") + "/Library/MobileDevice/Provisioning Profiles/*.mobileprovision"
|
190
|
+
Dir[profiles_path]
|
191
|
+
end
|
192
|
+
|
193
|
+
# @param [String] profile_path
|
194
|
+
# @return [Hash]
|
195
|
+
def profile_to_plist(profile_path)
|
196
|
+
File.open(profile_path) do |profile|
|
197
|
+
asn1 = OpenSSL::ASN1.decode(profile.read)
|
198
|
+
plist_str = asn1.value[1].value[0].value[2].value[1].value[0].value
|
199
|
+
plist = Plist.parse_xml plist_str.force_encoding('UTF-8')
|
200
|
+
plist['Path'] = profile_path
|
201
|
+
return plist
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def create_provisioning(identifier, uuid)
|
206
|
+
app = MemberCenters::App.new(identifier)
|
207
|
+
provisioning_prifile = MemberCenters::ProvisioningProfile.new(identifier)
|
208
|
+
|
209
|
+
begin
|
210
|
+
unless app.created?
|
211
|
+
app.create!
|
212
|
+
puts "App ID #{identifier} was created"
|
213
|
+
end
|
214
|
+
rescue => e
|
215
|
+
DeployGate::Message::Error.print("Error: Failed to create App ID")
|
216
|
+
raise e
|
217
|
+
end
|
218
|
+
|
219
|
+
begin
|
220
|
+
provisioning_profiles = provisioning_prifile.create!(uuid)
|
221
|
+
rescue => e
|
222
|
+
DeployGate::Message::Error.print("Error: Failed to create provisioning profile")
|
223
|
+
raise e
|
224
|
+
end
|
225
|
+
|
226
|
+
select_profile(provisioning_profiles)
|
227
|
+
end
|
228
|
+
|
229
|
+
# @param [Hash] teams
|
230
|
+
# @param [Hash] profiles
|
231
|
+
# @return [String]
|
232
|
+
def select_teams(teams, profiles)
|
233
|
+
result = nil
|
234
|
+
cli = HighLine.new
|
235
|
+
cli.choose do |menu|
|
236
|
+
menu.prompt = 'Please select team'
|
237
|
+
teams.each_with_index do |team, index|
|
238
|
+
menu.choice("#{team[1]} #{team[0]}") {
|
239
|
+
result = DeployGate::Xcode::Export.select_profile(profiles[team])
|
240
|
+
}
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
result
|
245
|
+
end
|
246
|
+
|
247
|
+
def check_local_certificates
|
248
|
+
if installed_distribution_certificate_ids.count == 0
|
249
|
+
# not local install certificate
|
250
|
+
DeployGate::Message::Error.print("Error: Not local install distribution certificate")
|
251
|
+
puts <<EOF
|
252
|
+
|
253
|
+
Not local install iPhone Distribution certificates.
|
254
|
+
Please install certificate.
|
255
|
+
|
256
|
+
Docs: https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html
|
257
|
+
|
258
|
+
EOF
|
259
|
+
exit
|
260
|
+
end
|
261
|
+
|
262
|
+
conflicting_certificates = installed_distribution_conflicting_certificates
|
263
|
+
if conflicting_certificates.count > 0
|
264
|
+
DeployGate::Message::Error.print("Error: Conflicting local install certificates")
|
265
|
+
puts <<EOF
|
266
|
+
|
267
|
+
Conflicting local install certificates.
|
268
|
+
Please uninstall certificates.
|
269
|
+
EOF
|
270
|
+
conflicting_certificates.each do |certificate|
|
271
|
+
puts certificate
|
272
|
+
end
|
273
|
+
puts ""
|
274
|
+
|
275
|
+
exit
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module DeployGate
|
2
|
-
module
|
2
|
+
module Xcode
|
3
3
|
module Ios
|
4
4
|
WORK_DIR_EXTNAME = '.xcworkspace'
|
5
5
|
PROJECT_DIR_EXTNAME = '.xcodeproj'
|
@@ -13,18 +13,26 @@ module DeployGate
|
|
13
13
|
# @param [String] codesigning_identity
|
14
14
|
# @param [String] export_method
|
15
15
|
# @return [String]
|
16
|
-
def build(ios_analyze, target_scheme, codesigning_identity, export_method = Export::AD_HOC)
|
17
|
-
raise NotSupportExportMethodError, 'Not support export' unless Export::SUPPORT_EXPORT_METHOD.include?(export_method)
|
16
|
+
def build(ios_analyze, target_scheme, codesigning_identity, export_method = DeployGate::Xcode::Export::AD_HOC)
|
17
|
+
raise NotSupportExportMethodError, 'Not support export' unless DeployGate::Xcode::Export::SUPPORT_EXPORT_METHOD.include?(export_method)
|
18
18
|
|
19
19
|
values = {
|
20
20
|
:export_method => export_method,
|
21
21
|
:workspace => ios_analyze.build_workspace,
|
22
|
-
:configuration => Analyze::BUILD_CONFIGRATION,
|
22
|
+
:configuration => DeployGate::Xcode::Analyze::BUILD_CONFIGRATION,
|
23
23
|
:scheme => target_scheme,
|
24
24
|
:codesigning_identity => codesigning_identity
|
25
25
|
}
|
26
26
|
v = FastlaneCore::Configuration.create(Gym::Options.available_options, values)
|
27
|
-
|
27
|
+
|
28
|
+
begin
|
29
|
+
absolute_ipa_path = File.expand_path(Gym::Manager.new.work(v))
|
30
|
+
rescue => e
|
31
|
+
# TODO: build error handling
|
32
|
+
use_xcode_path = `xcode-select -p`
|
33
|
+
DeployGate::Message::Error.print("Current Xcode used to build: #{use_xcode_path} (via xcode-select)")
|
34
|
+
raise e
|
35
|
+
end
|
28
36
|
absolute_dsym_path = absolute_ipa_path.gsub(".ipa", ".app.dSYM.zip") # TODO: upload to deploygate
|
29
37
|
|
30
38
|
absolute_ipa_path
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module DeployGate
|
4
|
+
module Xcode
|
5
|
+
class MemberCenter
|
6
|
+
include Singleton
|
7
|
+
attr_reader :email, :method
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@email = input_email
|
11
|
+
Spaceship.login @email
|
12
|
+
Spaceship.select_team
|
13
|
+
|
14
|
+
if Spaceship.client.in_house?
|
15
|
+
@method = Export::ENTERPRISE
|
16
|
+
else
|
17
|
+
@method = Export::AD_HOC
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean]
|
22
|
+
def adhoc?
|
23
|
+
@method == Export::AD_HOC
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Boolean]
|
27
|
+
def in_house?
|
28
|
+
@method == Export::ENTERPRISE
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# @return [String]
|
34
|
+
def input_email
|
35
|
+
puts <<EOF
|
36
|
+
|
37
|
+
No suitable provisioning profile found to export the app.
|
38
|
+
|
39
|
+
Please enter your email and password for Apple Developer Center
|
40
|
+
to set up/download provisioning profile automatically so you can
|
41
|
+
export the app without any extra steps.
|
42
|
+
|
43
|
+
Note: Your password will be stored to Keychain and never be sent to DeployGate.
|
44
|
+
|
45
|
+
EOF
|
46
|
+
print 'Email: '
|
47
|
+
STDIN.gets.chop
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module DeployGate
|
2
|
+
module Xcode
|
3
|
+
module MemberCenters
|
4
|
+
class App
|
5
|
+
attr_reader :uuid, :member_center
|
6
|
+
|
7
|
+
# @param [String] uuid
|
8
|
+
# @return [DeployGate::Xcode::MemberCenters::App]
|
9
|
+
def initialize(uuid)
|
10
|
+
@member_center = DeployGate::Xcode::MemberCenter.instance
|
11
|
+
@uuid = uuid
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Boolean]
|
15
|
+
def created?
|
16
|
+
Spaceship.app.all.collect do |app|
|
17
|
+
return true if app.bundle_id == @uuid
|
18
|
+
end
|
19
|
+
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [void]
|
24
|
+
def create!
|
25
|
+
Spaceship.app.create!(bundle_id: @uuid, name: name())
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String]
|
29
|
+
def name
|
30
|
+
@uuid.split('.').join(' ')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module DeployGate
|
2
|
+
module Xcode
|
3
|
+
module MemberCenters
|
4
|
+
class ProvisioningProfile
|
5
|
+
attr_reader :member_center, :app_identifier
|
6
|
+
|
7
|
+
OUTPUT_PATH = '/tmp/dg/provisioning_profile/'
|
8
|
+
CERTIFICATE_OUTPUT_PATH = '/tmp/dg/certificate/'
|
9
|
+
|
10
|
+
def initialize(app_identifier)
|
11
|
+
@member_center = DeployGate::Xcode::MemberCenter.instance
|
12
|
+
@app_identifier = app_identifier
|
13
|
+
|
14
|
+
FileUtils.mkdir_p(OUTPUT_PATH)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param [String] uuid
|
18
|
+
# @return [Array]
|
19
|
+
def create!(uuid = nil)
|
20
|
+
profiles = if uuid.nil?
|
21
|
+
all_create()
|
22
|
+
else
|
23
|
+
[download(uuid)]
|
24
|
+
end
|
25
|
+
|
26
|
+
profiles
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# @return [Array]
|
32
|
+
def all_create
|
33
|
+
if @member_center.adhoc?
|
34
|
+
prod_certs = Spaceship.certificate.production.all
|
35
|
+
else
|
36
|
+
prod_certs = Spaceship.certificate.all.reject{|cert| cert.class != Spaceship::Portal::Certificate::InHouse}
|
37
|
+
end
|
38
|
+
|
39
|
+
# check local install certificate
|
40
|
+
FileUtils.mkdir_p(CERTIFICATE_OUTPUT_PATH)
|
41
|
+
distribution_cert_ids = []
|
42
|
+
prod_certs.each do |cert|
|
43
|
+
path = File.join(CERTIFICATE_OUTPUT_PATH, "#{cert.id}.cer")
|
44
|
+
raw_data = cert.download_raw
|
45
|
+
File.write(path, raw_data)
|
46
|
+
distribution_cert_ids.push(cert.id) if FastlaneCore::CertChecker.installed?(path)
|
47
|
+
end
|
48
|
+
raise 'Not local install certificate' if distribution_cert_ids.empty?
|
49
|
+
|
50
|
+
provisionings = []
|
51
|
+
distribution_cert_ids.each do |cert_id|
|
52
|
+
values = sigh_config_values(cert_id: cert_id)
|
53
|
+
download_profile_path = download_profile(values)
|
54
|
+
provisionings.push(download_profile_path)
|
55
|
+
end
|
56
|
+
|
57
|
+
provisionings
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param [String] uuid
|
61
|
+
# @return [String]
|
62
|
+
def download(uuid)
|
63
|
+
profiles = Spaceship.provisioning_profile.all.reject!{|p| p.uuid != uuid}
|
64
|
+
|
65
|
+
raise 'Not Xcode selected Provisioning Profile' if profiles.empty?
|
66
|
+
select_profile = profiles.first
|
67
|
+
method = select_profile.kind_of?(Spaceship::Portal::ProvisioningProfile::AdHoc)
|
68
|
+
|
69
|
+
values = sigh_config_values(adhoc: method, provisioning_name: select_profile.name)
|
70
|
+
download_profile(values)
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param [Hash] values
|
74
|
+
# @return [String]
|
75
|
+
def download_profile(values)
|
76
|
+
config = FastlaneCore::Configuration.create(Sigh::Options.available_options, values)
|
77
|
+
Sigh.config = config
|
78
|
+
|
79
|
+
Sigh::Manager.start
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Hash]
|
83
|
+
def sigh_config_values(adhoc: @member_center.adhoc?, provisioning_name: nil, cert_id: nil)
|
84
|
+
values = {
|
85
|
+
adhoc: adhoc,
|
86
|
+
app_identifier: @app_identifier,
|
87
|
+
username: @member_center.email,
|
88
|
+
output_path: OUTPUT_PATH,
|
89
|
+
team_id: Spaceship.client.team_id
|
90
|
+
}
|
91
|
+
values.merge!({provisioning_name: provisioning_name}) unless provisioning_name.nil?
|
92
|
+
values.merge!({cert_id: cert_id}) unless cert_id.nil?
|
93
|
+
|
94
|
+
values
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/deploygate.rb
CHANGED
@@ -13,6 +13,10 @@ require "uuid"
|
|
13
13
|
require "gem_update_checker"
|
14
14
|
require "active_support/core_ext/time"
|
15
15
|
require "locale"
|
16
|
+
require "tempfile"
|
17
|
+
require "open3"
|
18
|
+
require "open-uri"
|
19
|
+
require "rexml/document"
|
16
20
|
|
17
21
|
# ios build
|
18
22
|
require "gym"
|
@@ -39,13 +43,18 @@ require "deploygate/config/credential"
|
|
39
43
|
require "deploygate/config/cache_version"
|
40
44
|
require "deploygate/session"
|
41
45
|
require "deploygate/deploy"
|
42
|
-
require "deploygate/
|
46
|
+
require "deploygate/project"
|
43
47
|
require "deploygate/user"
|
44
|
-
require "deploygate/builds/ios"
|
45
|
-
require "deploygate/builds/ios/export"
|
46
|
-
require "deploygate/builds/ios/analyze"
|
47
|
-
require "deploygate/builds/ios/set_profile"
|
48
48
|
require "deploygate/message/error"
|
49
49
|
require "deploygate/message/success"
|
50
50
|
require "deploygate/message/warning"
|
51
|
+
require "deploygate/xcode/member_center"
|
52
|
+
require "deploygate/xcode/member_centers/app"
|
53
|
+
require "deploygate/xcode/member_centers/provisioning_profile"
|
54
|
+
require "deploygate/xcode/export"
|
55
|
+
require "deploygate/xcode/analyze"
|
56
|
+
require "deploygate/xcode/ios"
|
57
|
+
require "deploygate/android/gradle_deploy"
|
58
|
+
require "deploygate/android/gradle_plugin_installer"
|
59
|
+
require "deploygate/android/gradle_project"
|
51
60
|
require "deploygate/version"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe DeployGate::Project do
|
2
|
+
describe "#ios?" do
|
3
|
+
it "when select workspace" do
|
4
|
+
allow(DeployGate::Xcode::Ios).to receive(:ios_root?).and_return(false)
|
5
|
+
allow(DeployGate::Xcode::Ios).to receive(:workspace?).and_return(true)
|
6
|
+
allow(DeployGate::Xcode::Ios).to receive(:project?).and_return(false)
|
7
|
+
|
8
|
+
result = DeployGate::Project.ios?('path')
|
9
|
+
expect(result).to be_truthy
|
10
|
+
end
|
11
|
+
|
12
|
+
it "when workspaces" do
|
13
|
+
allow(DeployGate::Xcode::Ios).to receive(:ios_root?).and_return(false)
|
14
|
+
allow(DeployGate::Xcode::Ios).to receive(:workspace?).and_return(false)
|
15
|
+
allow(DeployGate::Xcode::Ios).to receive(:project?).and_return(true)
|
16
|
+
|
17
|
+
result = DeployGate::Project.ios?('path')
|
18
|
+
expect(result).to be_truthy
|
19
|
+
end
|
20
|
+
|
21
|
+
it "not ios" do
|
22
|
+
allow(DeployGate::Xcode::Ios).to receive(:ios_root?).and_return(false)
|
23
|
+
allow(DeployGate::Xcode::Ios).to receive(:workspace?).and_return(false)
|
24
|
+
allow(DeployGate::Xcode::Ios).to receive(:project?).and_return(false)
|
25
|
+
|
26
|
+
result = DeployGate::Project.ios?('path')
|
27
|
+
expect(result).to be_falsey
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#android?" do
|
32
|
+
it "android project" do
|
33
|
+
allow(DeployGate::Android::GradleProject).to receive(:root_dir?).and_return(true)
|
34
|
+
|
35
|
+
result = DeployGate::Project.android?('path')
|
36
|
+
expect(result).to be_truthy
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|