xcode-utils 1.0.0 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/lib/xcutils/carthage/xcconfig.rb +3 -3
- data/lib/xcutils/{carthage/colors.rb → colors.rb} +0 -0
- data/lib/xcutils/uitest.rb +107 -63
- data/lib/xcutils/version.rb +1 -1
- data/templates/UITestRunner/Base/UITestAuthorizationProvider.swift +1 -3
- data/templates/UITestRunner/Base/UITestSuite.swift +14 -10
- data/templates/UITestRunner/Suites/MainTestSuite.swift +1 -3
- data/templates/UITestRunner/UITestAuthorizationProviderImpl.swift +1 -3
- data/templates/UITestRunner/UITestRunnerViewController.swift +13 -10
- metadata +16 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae6a88462f11625079d48f69db98fc5300fbdf733598fa2b2bfef97946d628e2
|
4
|
+
data.tar.gz: cf5857085391c9b590ea301f5bb63d9e9feeed83f35d99c40d0c32ca7f058dc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 804232e58a8061b39d83f1db06a7afa9d8b73ce0d576d8991e45c7f3abd8fb9df9e75661425f5358907dc95f5d34e88b52bfe6eae8810db5508c1f28c144f3da
|
7
|
+
data.tar.gz: b268b7a14c2d79eb96fd923e91bf1888b241c1d706b023397b66452b92a0d65be4a10cdfda36785f32a67a13b0a5ccdf1a799664ca1bf8f21cae578e1ccb5472
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Xcode::Utils
|
2
2
|
|
3
|
-
[![Gem Version](
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/xcode-utils.svg)](https://badge.fury.io/rb/xcode-utils)
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -9,6 +9,7 @@ $ gem install xcode-utils
|
|
9
9
|
```
|
10
10
|
|
11
11
|
## UITestRunner
|
12
|
+
Make available single test page in app as standalone
|
12
13
|
|
13
14
|
### Install UITestRunner in your xcode project
|
14
15
|
```
|
@@ -121,4 +122,4 @@ $ xcutils carthage clean
|
|
121
122
|
|
122
123
|
This project is licensed under the terms of the MIT license. See the [LICENSE](LICENSE) file.
|
123
124
|
|
124
|
-
> This project and all fastlane tools are in no way affiliated with Apple Inc or Google. This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs. All fastlane tools run on your own computer or server, so your credentials or other sensitive information will never leave your own computer. You are responsible for how you use fastlane tools.
|
125
|
+
> This project and all fastlane tools are in no way affiliated with Apple Inc or Google. This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs. All fastlane tools run on your own computer or server, so your credentials or other sensitive information will never leave your own computer. You are responsible for how you use fastlane tools.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'xcodeproj'
|
2
|
-
require 'xcutils/
|
2
|
+
require 'xcutils/colors'
|
3
3
|
|
4
4
|
module XcodeUtils
|
5
5
|
module Carthage
|
@@ -24,13 +24,13 @@ module XcodeUtils
|
|
24
24
|
|
25
25
|
def open_project
|
26
26
|
if !Dir.exist?(@build_path)
|
27
|
-
abort
|
27
|
+
abort "😭 The Carthage build has not yet been successful. Please try again after successful arthage build.".red
|
28
28
|
end
|
29
29
|
|
30
30
|
project_names = Dir["./*.xcodeproj"]
|
31
31
|
|
32
32
|
if project_names.first.nil?
|
33
|
-
abort
|
33
|
+
abort "😭 Does not exist project to configure.".red
|
34
34
|
end
|
35
35
|
|
36
36
|
puts "💎💎 Project Found -> #{project_names.first} 💎💎"
|
File without changes
|
data/lib/xcutils/uitest.rb
CHANGED
@@ -1,27 +1,29 @@
|
|
1
1
|
require 'xcodeproj'
|
2
2
|
require 'plist'
|
3
3
|
require 'nokogiri'
|
4
|
+
require 'xcutils/colors'
|
4
5
|
|
5
6
|
module XcodeUtils
|
6
7
|
class Command
|
7
8
|
class UITest < Command
|
8
9
|
self.abstract_command = true
|
9
10
|
self.command = 'uitest'
|
11
|
+
self.summary = 'UITestRunner installer.'
|
10
12
|
|
11
13
|
class Install < UITest
|
12
14
|
self.summary = 'Install uitest.'
|
13
15
|
|
14
16
|
self.arguments = [
|
15
17
|
CLAide::Argument.new('PROJECT_NAME', :true),
|
16
|
-
CLAide::Argument.new('
|
17
|
-
CLAide::Argument.new('
|
18
|
+
CLAide::Argument.new('TARGET_CONFIG_NAME', :true),
|
19
|
+
CLAide::Argument.new('TARGET_SCHEME_NAME', :true)
|
18
20
|
]
|
19
21
|
|
20
22
|
def self.options
|
21
23
|
[
|
22
|
-
['--project-name
|
23
|
-
['--target-config
|
24
|
-
['--target-scheme
|
24
|
+
['--project-name', 'The name of your xcode project'],
|
25
|
+
['--target-config', 'The name of build configuration to be copied to uitestrunner build configuration'],
|
26
|
+
['--target-scheme', 'The name of build scheme to be copied to uitestrunner build scheme'],
|
25
27
|
]
|
26
28
|
end
|
27
29
|
|
@@ -43,69 +45,108 @@ module XcodeUtils
|
|
43
45
|
end
|
44
46
|
|
45
47
|
def run
|
48
|
+
puts "Input: project_name: #{@project_name}, target_config: #{@taget_config}, target_scheme: #{@target_scheme}"
|
49
|
+
open_project
|
50
|
+
generate_project_configuration
|
46
51
|
generate_build_configuration
|
47
|
-
|
52
|
+
generate_scheme_file
|
48
53
|
copy_template_files
|
54
|
+
|
55
|
+
if !@project.nil?
|
56
|
+
@project.save()
|
57
|
+
puts "🦾 Installing Completed".green
|
58
|
+
end
|
49
59
|
end
|
50
|
-
|
51
|
-
def
|
52
|
-
puts "
|
60
|
+
|
61
|
+
def open_project
|
62
|
+
puts "🤖 Installing #{@uitest_name} into #{@project_name}".green
|
63
|
+
|
64
|
+
if !Dir.exist?(@project_path)
|
65
|
+
abort "😭 Abort to install. Project #{project_name} does not exist".red
|
66
|
+
end
|
67
|
+
@project = Xcodeproj::Project.open(@project_path)
|
68
|
+
end
|
69
|
+
|
70
|
+
def generate_project_configuration
|
71
|
+
puts "Generating project configuration #{@uitest_name} into #{@project_name}"
|
53
72
|
|
54
|
-
|
55
|
-
configuration_list = project.root_object.build_configuration_list
|
73
|
+
configuration_list = @project.root_object.build_configuration_list
|
56
74
|
|
57
75
|
if configuration_list.build_settings(@uitest_name) != nil
|
58
|
-
puts "
|
76
|
+
puts "Skip to generate project configuration for #{@uitest_name}. It is already installed in the project #{@project_name}".gray
|
59
77
|
return
|
60
78
|
end
|
61
79
|
|
62
|
-
|
63
|
-
puts "Generating project configuration"
|
64
|
-
|
65
|
-
configuration = project.new(Xcodeproj::Project::Object::XCBuildConfiguration)
|
80
|
+
configuration = @project.new(Xcodeproj::Project::Object::XCBuildConfiguration)
|
66
81
|
configuration.name = @uitest_name
|
67
82
|
configuration.build_settings = configuration_list.build_settings(@taget_config)
|
68
83
|
configuration_list.build_configurations << configuration
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
base_config = target.build_configurations.select { |e| e.name == @taget_config }.first
|
76
|
-
org_main_storyboard_file = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def generate_build_configuration
|
87
|
+
@project.targets.each { |target|
|
88
|
+
target_config = target.build_configurations.select { |e| e.name == @taget_config }.first
|
89
|
+
target_main_sb = nil
|
77
90
|
|
78
91
|
target.build_configurations.each { |e|
|
92
|
+
break if e.name == @uitest_name
|
93
|
+
|
94
|
+
puts "Configure build configuration #{e.name} in #{target.name}"
|
95
|
+
|
79
96
|
path = e.build_settings['INFOPLIST_FILE']
|
80
|
-
|
81
|
-
|
82
|
-
e.build_settings['MAIN_STORYBOARD_FILE']
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
97
|
+
plist = Plist.parse_xml(path)
|
98
|
+
plist_main_sb = plist['UIMainStoryboardFile']
|
99
|
+
build_settings_main_sb = e.build_settings['MAIN_STORYBOARD_FILE']
|
100
|
+
variable_name = '$(MAIN_STORYBOARD_FILE)'
|
101
|
+
is_not_variable = plist_main_sb != variable_name
|
102
|
+
|
103
|
+
e.build_settings['MAIN_STORYBOARD_FILE'] = is_not_variable ? plist_main_sb : (target_main_sb != nil ? target_main_sb : build_settings_main_sb)
|
104
|
+
|
105
|
+
if target_main_sb.nil?
|
106
|
+
target_main_sb = build_settings_main_sb
|
87
107
|
end
|
108
|
+
|
109
|
+
plist['UIMainStoryboardFile'] = variable_name
|
88
110
|
|
89
|
-
|
111
|
+
if is_not_variable
|
112
|
+
File.write(path, plist.to_plist)
|
113
|
+
end
|
114
|
+
|
115
|
+
file_names_string = e.build_settings['EXCLUDED_SOURCE_FILE_NAMES']
|
116
|
+
file_names_string = appended(file_names_string, '$(SRCROOT)/$(PRODUCT_NAME)/UITestRunner/*')
|
117
|
+
file_names_string = appended(file_names_string, '$(SRCROOT)/$(PRODUCT_NAME)/UITestRunner/**/*')
|
118
|
+
e.build_settings['EXCLUDED_SOURCE_FILE_NAMES'] = file_names_string
|
90
119
|
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
120
|
+
|
121
|
+
test_config = target.build_configurations.select { |e| e.name == @uitest_name }.first
|
122
|
+
|
123
|
+
if test_config.nil?
|
124
|
+
puts "Generating build configuration #{@uitest_name} into #{target.name}"
|
125
|
+
new_config = @project.new(Xcodeproj::Project::Object::XCBuildConfiguration)
|
126
|
+
new_config.name = @uitest_name
|
127
|
+
new_config.base_configuration_reference = target_config.base_configuration_reference
|
128
|
+
target.build_configurations << new_config
|
129
|
+
else
|
130
|
+
puts "Configure build configuration #{@uitest_name} in #{target.name}"
|
131
|
+
new_config = test_config
|
132
|
+
end
|
133
|
+
|
134
|
+
new_config.build_settings.update(target_config.build_settings)
|
96
135
|
new_config.build_settings['MAIN_STORYBOARD_FILE'] = @uitest_name
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
puts "Generating scheme #{target.name} #{@uitest_name}"
|
101
|
-
|
102
|
-
project.save()
|
103
|
-
end
|
136
|
+
new_config.build_settings['EXCLUDED_SOURCE_FILE_NAMES'] = nil
|
137
|
+
}
|
104
138
|
end
|
105
139
|
|
106
|
-
def
|
140
|
+
def generate_scheme_file
|
107
141
|
scheme_name = "#{@project_name} #{@uitest_name}"
|
142
|
+
|
143
|
+
if File.exist?(scheme_path(scheme_name))
|
144
|
+
puts "Skip to generate. A scheme file is already exsit, #{scheme_name}".gray
|
145
|
+
return
|
146
|
+
end
|
108
147
|
|
148
|
+
puts "Generating scheme file #{scheme_path(scheme_name)}"
|
149
|
+
|
109
150
|
FileUtils.copy_file(scheme_path(@target_scheme), scheme_path(scheme_name))
|
110
151
|
|
111
152
|
scheme = Xcodeproj::XCScheme.new(scheme_path(scheme_name))
|
@@ -114,29 +155,32 @@ module XcodeUtils
|
|
114
155
|
end
|
115
156
|
|
116
157
|
def copy_template_files
|
117
|
-
|
118
|
-
|
119
|
-
if Dir.exist?(template_path)
|
120
|
-
puts "Template files already exist in the project #{@project_name}"
|
121
|
-
return
|
122
|
-
end
|
123
|
-
|
124
|
-
puts "Copying template files into project #{@project_name}"
|
158
|
+
puts "Adding references for files and resources into project #{@project_name}"
|
125
159
|
|
126
|
-
|
127
|
-
|
160
|
+
@project.targets.each { |target|
|
161
|
+
template_path = "./#{target.name}/#{@uitest_name}"
|
128
162
|
|
129
|
-
|
163
|
+
if !Dir.exist?(template_path)
|
164
|
+
puts "Copying template files into target #{target.name}"
|
165
|
+
path = File.expand_path('../../../templates', __FILE__)
|
166
|
+
FileUtils.copy_entry path, "./#{target.name}"
|
167
|
+
else
|
168
|
+
puts "Skip to copy template files. Files are already exsit".gray
|
169
|
+
end
|
130
170
|
|
131
|
-
|
171
|
+
target_group = @project.groups.select { |e| e.path == target.name }.first
|
132
172
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
173
|
+
if target_group.groups.select { |e| e.path == @uitest_name }.first.nil?
|
174
|
+
template_group = target_group.new_group(nil, @uitest_name)
|
175
|
+
add_files("#{template_path}/*", template_group, target)
|
176
|
+
end
|
137
177
|
}
|
138
|
-
|
139
|
-
|
178
|
+
end
|
179
|
+
|
180
|
+
def appended(string, other)
|
181
|
+
return other if string == nil
|
182
|
+
return string if string.include? other
|
183
|
+
return string << " #{other}"
|
140
184
|
end
|
141
185
|
|
142
186
|
def add_files(direc, current_group, main_target)
|
data/lib/xcutils/version.rb
CHANGED
@@ -3,12 +3,10 @@
|
|
3
3
|
// Copyright © 2020 abc-studio. All rights reserved.
|
4
4
|
//
|
5
5
|
|
6
|
-
#if DEBUG
|
7
6
|
protocol UITestAuthorizationProvider {
|
8
7
|
var hasAccessToken: Bool {get}
|
9
8
|
var hasRefreshToken: Bool {get}
|
10
9
|
func refreshToken(completion: @escaping () -> Void)
|
11
10
|
func signIn(_ parent: UIViewController, completion: @escaping () -> Void)
|
12
11
|
func signOut()
|
13
|
-
}
|
14
|
-
#endif
|
12
|
+
}
|
@@ -3,7 +3,6 @@
|
|
3
3
|
// Copyright © 2020 abc-studio. All rights reserved.
|
4
4
|
//
|
5
5
|
|
6
|
-
#if DEBUG
|
7
6
|
import Foundation
|
8
7
|
|
9
8
|
protocol UITestSuiteInitializable {
|
@@ -20,13 +19,14 @@ class UITestSuite: UITestSuiteInitializable {
|
|
20
19
|
|
21
20
|
static var authorizationProvider: UITestAuthorizationProvider?
|
22
21
|
|
23
|
-
var
|
24
|
-
var useLogin = true
|
25
|
-
var testRunnerViewController: UITestRunnerViewController! {
|
22
|
+
weak var testRunnerViewController: UITestRunnerViewController! {
|
26
23
|
didSet {
|
27
24
|
setUp()
|
28
25
|
}
|
29
26
|
}
|
27
|
+
|
28
|
+
var isNewSession = false
|
29
|
+
var useLogin = true
|
30
30
|
var view: UIView {
|
31
31
|
return testRunnerViewController.view
|
32
32
|
}
|
@@ -62,7 +62,7 @@ class UITestSuite: UITestSuiteInitializable {
|
|
62
62
|
logout()
|
63
63
|
signIn()
|
64
64
|
} else {
|
65
|
-
Self.authorizationProvider?.
|
65
|
+
Self.authorizationProvider?.refreshToken {
|
66
66
|
self.runTests()
|
67
67
|
}
|
68
68
|
}
|
@@ -86,12 +86,16 @@ class UITestSuite: UITestSuiteInitializable {
|
|
86
86
|
}
|
87
87
|
|
88
88
|
extension UITestSuite {
|
89
|
+
func present(_ viewController: UIViewController, animated: Bool = false, completion: (() -> Void)? = nil) {
|
90
|
+
viewController.modalPresentationStyle = .fullScreen
|
91
|
+
testRunnerViewController.present(viewController, animated: animated, completion: completion)
|
92
|
+
}
|
93
|
+
|
89
94
|
@discardableResult
|
90
|
-
func present(
|
91
|
-
let navigationController = UINavigationController(rootViewController:
|
95
|
+
func present(rootViewController: UIViewController, animated: Bool = false, completion: (() -> Void)? = nil) -> UINavigationController {
|
96
|
+
let navigationController = UINavigationController(rootViewController: rootViewController)
|
92
97
|
navigationController.modalPresentationStyle = .fullScreen
|
93
|
-
testRunnerViewController.present(navigationController, animated:
|
98
|
+
testRunnerViewController.present(navigationController, animated: animated, completion: completion)
|
94
99
|
return navigationController
|
95
100
|
}
|
96
|
-
}
|
97
|
-
#endif
|
101
|
+
}
|
@@ -3,7 +3,6 @@
|
|
3
3
|
// Copyright © 2020 abc-studio. All rights reserved.
|
4
4
|
//
|
5
5
|
|
6
|
-
#if DEBUG
|
7
6
|
import Foundation
|
8
7
|
|
9
8
|
final class MainTestSuite: UITestSuite {
|
@@ -24,5 +23,4 @@ final class MainTestSuite: UITestSuite {
|
|
24
23
|
private func testExample() {
|
25
24
|
// This is an example of a functional test case.
|
26
25
|
}
|
27
|
-
}
|
28
|
-
#endif
|
26
|
+
}
|
@@ -3,7 +3,6 @@
|
|
3
3
|
// Copyright © 2020 abc-studio. All rights reserved.
|
4
4
|
//
|
5
5
|
|
6
|
-
#if DEBUG
|
7
6
|
struct UITestAuthorizationProviderImpl: UITestAuthorizationProvider {
|
8
7
|
|
9
8
|
// MARK: - Implementations of Protocol UITestAuthorizationProvider
|
@@ -23,5 +22,4 @@ struct UITestAuthorizationProviderImpl: UITestAuthorizationProvider {
|
|
23
22
|
|
24
23
|
func signOut() {
|
25
24
|
}
|
26
|
-
}
|
27
|
-
#endif
|
25
|
+
}
|
@@ -3,36 +3,39 @@
|
|
3
3
|
// Copyright © 2020 abc-studio. All rights reserved.
|
4
4
|
//
|
5
5
|
|
6
|
-
#if DEBUG
|
7
6
|
import UIKit
|
8
7
|
|
9
8
|
final class UITestRunnerViewController: UIViewController {
|
10
9
|
|
10
|
+
// MARK: - Private Properties
|
11
|
+
|
12
|
+
private var suite: UITestSuite!
|
13
|
+
|
11
14
|
// MARK: - Overridden: UIViewController
|
12
15
|
|
13
16
|
override func viewDidLoad() {
|
14
17
|
super.viewDidLoad()
|
15
18
|
|
16
|
-
title = "UITestRunner"
|
17
|
-
|
18
19
|
UITestSuite.authorizationProvider = UITestAuthorizationProviderImpl()
|
20
|
+
}
|
19
21
|
|
20
|
-
|
22
|
+
override func viewDidAppear(_ animated: Bool) {
|
23
|
+
super.viewDidAppear(animated)
|
24
|
+
|
25
|
+
if children.count < 1 {
|
26
|
+
runTestSuites()
|
27
|
+
}
|
21
28
|
}
|
22
|
-
|
23
|
-
// MARK: - Private Properties
|
24
|
-
|
25
|
-
private var suite: UITestSuite!
|
26
29
|
|
27
30
|
// MARK: - Private Methods
|
28
31
|
|
29
32
|
private func runTestSuites() {
|
30
33
|
runTestSuite(MainTestSuite.self)
|
31
34
|
}
|
35
|
+
|
32
36
|
private func runTestSuite<T: UITestSuite>(_ suiteType: T.Type) {
|
33
37
|
suite = suiteType.init()
|
34
38
|
suite.testRunnerViewController = self
|
35
39
|
suite.run()
|
36
40
|
}
|
37
|
-
}
|
38
|
-
#endif
|
41
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcode-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Kim
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: claide
|
@@ -94,16 +94,22 @@ dependencies:
|
|
94
94
|
name: bundler
|
95
95
|
requirement: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
|
-
- - "
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 1.7.0
|
100
|
+
- - "<"
|
98
101
|
- !ruby/object:Gem::Version
|
99
|
-
version: '
|
102
|
+
version: '3.0'
|
100
103
|
type: :development
|
101
104
|
prerelease: false
|
102
105
|
version_requirements: !ruby/object:Gem::Requirement
|
103
106
|
requirements:
|
104
|
-
- - "
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.7.0
|
110
|
+
- - "<"
|
105
111
|
- !ruby/object:Gem::Version
|
106
|
-
version: '
|
112
|
+
version: '3.0'
|
107
113
|
description: Xcode utils provides uitest and carthage proxy
|
108
114
|
email:
|
109
115
|
- pisces@linecorp.com
|
@@ -117,8 +123,8 @@ files:
|
|
117
123
|
- bin/xcutils
|
118
124
|
- lib/xcutils.rb
|
119
125
|
- lib/xcutils/carthage.rb
|
120
|
-
- lib/xcutils/carthage/colors.rb
|
121
126
|
- lib/xcutils/carthage/xcconfig.rb
|
127
|
+
- lib/xcutils/colors.rb
|
122
128
|
- lib/xcutils/command.rb
|
123
129
|
- lib/xcutils/uitest.rb
|
124
130
|
- lib/xcutils/version.rb
|
@@ -134,7 +140,7 @@ homepage: https://git.linecorp.com/abc/xcode-utils.git
|
|
134
140
|
licenses:
|
135
141
|
- MIT
|
136
142
|
metadata: {}
|
137
|
-
post_install_message:
|
143
|
+
post_install_message:
|
138
144
|
rdoc_options: []
|
139
145
|
require_paths:
|
140
146
|
- lib
|
@@ -150,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
156
|
version: '0'
|
151
157
|
requirements: []
|
152
158
|
rubygems_version: 3.1.4
|
153
|
-
signing_key:
|
159
|
+
signing_key:
|
154
160
|
specification_version: 4
|
155
161
|
summary: Xcode utils
|
156
162
|
test_files: []
|