Compare commits

...

108 Commits

Author SHA1 Message Date
leavez
89501cc8ad a 2019-05-19 03:44:15 +08:00
leavez
17d831900e Update data_flow.rb 2019-05-19 03:44:00 +08:00
leavez
fee45fa673 Update spec_helper.rb 2019-05-19 03:43:28 +08:00
leavez
0a65ee51b1 cache generate_framework_path in sanbox 2019-05-19 03:42:09 +08:00
leavez
cbdc1ce12f remove legacy prebuild_pod_targets 2019-05-19 03:41:12 +08:00
leavez
79fa80281e typo 2019-05-19 03:40:04 +08:00
Leavez
081bd04a73 UT for retry 2019-05-17 00:28:25 +08:00
leavez
d5a8689c81 remove test code 2019-05-05 01:28:33 +08:00
leavez
89cf075d2d retry 2019-05-05 01:21:13 +08:00
leavez
63573b4d6f rename method 2019-05-03 00:33:53 +08:00
leavez
dc33ad7771 c 2019-05-03 00:01:22 +08:00
leavez
c4dcd864ec b 2019-05-01 10:26:36 +08:00
Leavez
648dc28ef6 a 2019-04-30 18:56:40 +08:00
Leavez
008b66efb0 UT:prebuild_targets 2019-04-30 15:51:52 +08:00
Leavez
c8963a2638 enable should in spec 2019-04-29 17:00:27 +08:00
Leavez
c2e6276df0 Update patch_method_when.rb 2019-04-29 16:54:48 +08:00
Leavez
d785eed5d5 UT: Patch method when 2019-04-29 16:53:56 +08:00
Leavez
8caedcd14c split files 2019-04-29 16:53:39 +08:00
Leavez
42a3961602 UT: patch_method 2019-04-29 16:42:21 +08:00
leavez
1d27ce416e a 2019-04-29 01:55:56 +08:00
leavez
e2467655aa add Flow file and comments 2019-04-29 01:31:30 +08:00
Leavez
3b30cb4cdb Merge branch 'master' into different_subspec 2019-04-28 18:46:11 +08:00
Leavez
ee88e50250 update gemfile for demo 2019-04-28 17:58:04 +08:00
Leavez
2f3c241208 add gemfile to test 2019-04-28 17:47:50 +08:00
Leavez
839d474667 fix merge 2019-04-28 17:35:35 +08:00
Leavez
298643214c fix compile failed log printing 2019-04-28 17:30:30 +08:00
Leavez
c1a2d532ee fix watchos simulator bianry missing 2019-04-28 17:28:57 +08:00
Leavez
bfe047c58d simplify test.sh 2019-04-28 16:38:41 +08:00
Leavez
87b9bb8bb2 fix for merge 2019-04-28 13:43:56 +08:00
Leavez
c9810c15b7 fix test compile for xcode 10.2 2019-04-28 12:16:15 +08:00
Leavez
551bc5bb20 Merge branch '0.4.4' 2019-04-28 12:01:47 +08:00
leavez
668abc78ab bump to 0.4.4 2019-04-28 01:39:36 +08:00
leavez
fe6d66649b add doc 2019-04-28 01:32:09 +08:00
leavez
87d024fc38 Merge branch 'custom_options' into 0.4.4 2019-04-28 01:11:59 +08:00
leavez
786d0bdeb9 add check for path 2019-04-28 01:10:21 +08:00
leavez
f133b18686 a 2019-04-28 01:02:18 +08:00
leavez
3a3aa06c68 add universal patch methods 2019-04-28 00:38:34 +08:00
leavez
42c38e1287 move files 2019-04-27 22:07:33 +08:00
leavez
c5a0dc181e move prebuild_pod_targets to new file 2019-04-27 21:59:43 +08:00
Leave
5a10c33e43
Merge pull request #67 from leavez/log
Add more detail log for one pod has multiple targets
2019-04-27 21:39:29 +08:00
leavez
3e59fae97c fix all the return in block 2019-04-27 20:51:34 +08:00
leavez
398147ca5f move check earlier 2019-04-24 02:35:54 +08:00
leavez
dc3b3691b6 fix 2019-04-24 02:34:38 +08:00
leavez
614915ebcd add a early pods checking and enrich the log 2019-04-24 02:12:10 +08:00
leavez
d6c9c13a14 add log for target missing in Pod.xcproj 2019-04-23 23:20:54 +08:00
leavez
16f17faead add log for skipped prebuilding pod 2019-04-23 22:53:51 +08:00
Leave
0af792fac0
Merge branch '0.5.0' into custom_options 2019-04-17 14:27:43 +08:00
Leavez
e2b96c462a Merge generated swift headers for xcode 10.2
close #58
2019-04-17 14:08:01 +08:00
Leavez
e8997b7a10 fix typo 2019-04-17 13:37:10 +08:00
leavez
00b2fd64f4 add ISSUE_TEMPLATE
closes #61
2019-04-17 02:03:54 +08:00
Leavez
41b2b46d4c add demo project 2019-04-16 19:50:53 +08:00
Leavez
84cdaa6f8d add demo folder 2019-04-16 19:42:47 +08:00
Leavez
bdabee15ac bump to 0.4.3 2019-04-01 13:01:38 +08:00
Leavez
ab914346a4 fix #50 2019-04-01 13:00:31 +08:00
leavez
3043ef216f ensure lipo dsym won't generate error if non-exist 2019-03-29 01:56:43 +08:00
leavez
e732532816 fix for non-compiling error printing 2019-03-29 01:47:02 +08:00
leavez
097527ab1f make sure xcpretty won't crash, as it's not improtant 2019-03-29 01:21:13 +08:00
leavez
10415b4a42 Update build_framework.rb 2019-03-29 01:19:44 +08:00
leavez
31f65ef345 use xcpretty to print fail log 2019-03-29 01:19:30 +08:00
Leavez
8ef3d11c8a fix #50 2019-03-26 20:42:40 +08:00
leavez
9f40c5df41 Merge branch '0.4.2' 2019-03-25 00:39:24 +08:00
leavez
d51dc68409 abort when build error 2019-03-24 23:48:35 +08:00
leavez
b2ef58c49b add API for custom_build_option 2019-03-24 23:22:16 +08:00
leavez
7965225d8e add custom_build_option for buiding 2019-03-24 22:03:24 +08:00
Leave
012c326cca
Update README.md 2019-03-18 01:45:09 +08:00
Leave
5470ecb188 Merge pull request #48 from leavez/dsym
fix missing of dSYM for dynamic framework
2019-03-18 01:38:21 +08:00
Leave
b4d149267b
Merge pull request #32 from dev4dev/bitcode-fix
Added missing flag for enabling bitcode
2019-03-17 18:27:12 +08:00
Leave
345b35ef94
Merge pull request #47 from hardworker/update_options_passing
Update behaviour fixing (issue #38)
2019-03-11 20:23:47 +08:00
hardworker
1d1b193962 Added additional explanation comments, moved from instance variables to local ones 2019-03-09 16:41:04 +03:00
hardworker
e9e041740f Fixed update command options passing by inspecting original Pod::Installer (issue #38) 2019-03-06 02:36:23 +03:00
Leave
baf2f144f3
Update README.md 2019-03-05 01:33:28 +08:00
Leave
c0dfbb1cee
Merge pull request #45 from leavez/fix#29
Fix #29
2019-03-05 01:30:57 +08:00
leavez
537e8557ac fix resource_bundle bugs when static framework
fix https://github.com/leavez/cocoapods-binary/issues/29
2019-03-05 01:04:01 +08:00
hardworker
ef8c551b0f Added lockfile parameter passing to installer initializer 2019-02-27 01:14:09 +08:00
X140Yu
2b22adce9b
Update log 2019-01-18 16:08:37 +08:00
Leave
744765583e
Update README.md 2019-01-16 20:04:28 +08:00
Alex Antonyuk
d3d153a68a Added missing flag for enabling bitcode 2019-01-09 10:41:07 +02:00
leavez
d3f529d1d9 fix the checking 2018-07-11 01:41:23 +08:00
leavez
988a09f7ac fix validate_every_pod_only_have_one_form 2018-07-11 00:32:58 +08:00
leavez
62af283ecd fix pod_name_for_target_folder 2018-07-11 00:32:58 +08:00
leavez
971381a4ab don't print warning for prebuild step when finished 2018-07-08 02:16:41 +08:00
Leave
cfc63e1f38
Merge pull request #26 from leavez/watch
support multiple platform simultaneously (e.g. watchOS and iOS)
2018-07-08 02:14:25 +08:00
leavez
589bc22574 add content in test 2018-07-08 01:44:58 +08:00
leavez
3333385db6 fix test 2018-07-08 01:28:38 +08:00
leavez
d234833546 fix validate_every_pod_only_have_one_form 2018-07-08 00:58:07 +08:00
leavez
cdc913a5a3 fix test 2018-07-07 22:53:37 +08:00
leavez
6586f404f1 add test for multiplePlatforms 2018-07-07 22:40:55 +08:00
leavez
250ee365e4 add target for test 2018-07-07 22:31:37 +08:00
leavez
4f0d0c87cb add check for different forms 2018-07-07 22:23:29 +08:00
leavez
702f5020bc fix save_pod_name_for_target 2018-07-07 21:06:59 +08:00
leavez
01430ed68c fix pod_name_for_target_folder 2018-07-07 20:46:20 +08:00
leavez
99f90d8e5a fix the pod_name_target finding 2018-07-07 20:30:11 +08:00
leavez
ad15231e7c add compatibility with older version 2018-07-07 19:39:55 +08:00
leavez
d78acb3b57 add comments 2018-07-07 19:29:10 +08:00
leavez
c5efe4350c refactor patch integration to support multiple platfroms 2018-07-07 19:21:40 +08:00
leavez
411965ed2e refactor pod_name and target_name tranfrom 2018-07-07 19:18:27 +08:00
leavez
c1e876e62a fix name usages 2.2 2018-07-07 16:14:18 +08:00
leavez
58eeb3f4c5 fix name usage 2.1 2018-07-07 15:57:41 +08:00
leavez
c80d9ba699 fix name usage 2 2018-07-07 15:54:35 +08:00
leavez
4c2a3ad06b add comments for names 2018-07-07 03:53:32 +08:00
leavez
31fdc383ab organize name usages 2018-07-07 03:44:01 +08:00
leavez
a8985c5264 installing prebuild pod support multiple platforms 2018-07-07 03:06:02 +08:00
leavez
710839eafd rename framework_folder_path_for_pod_name to framework_folder_path_for_target_name 2018-07-07 02:04:09 +08:00
leavez
1e357dc100 simplify label with target.name 2018-07-07 01:41:46 +08:00
leavez
cfe476404a rome supports build watchos 2018-07-07 01:14:25 +08:00
leavez
69bc8c3788 fix prebuild framework paths when have multiple platforms 2018-07-07 01:13:37 +08:00
leavez
2238d25dc2 remove filter for watchos 2018-07-04 23:59:53 +08:00
leavez
c44e490a7d add logo 2018-07-04 23:34:44 +08:00
69 changed files with 4000 additions and 401 deletions

10
.github/ISSUE_TEMPLATE vendored Normal file
View File

@ -0,0 +1,10 @@
Thanks for your feedback!
If it's a bug:
- What's your environment:
- run ` pod env | egrep 'CocoaPods |Xcode|cocoapods-binary' ` then paste the result here
- A demo project is helpful:
- It will be very helpful if provides a demo project that reproduce the problem. A blank project with cocoapods-binary can be downloaded [here](https://github.com/leavez/cocoapods-binary/files/3086250/BinaryDemo.zip), which can be remodeled to a minimal problematic environment. Attach the demo.zip to the comments.

1
.gitignore vendored
View File

@ -3,6 +3,7 @@ pkg
.idea/
test/Pods
test/Gemfile.lock
## Various settings
*.pbxuser

View File

@ -4,10 +4,11 @@ source 'https://rubygems.org'
gemspec
group :development do
gem 'cocoapods'
gem 'cocoapods', '1.6.1'
gem 'mocha'
gem 'bacon'
gem 'mocha-on-bacon'
gem 'prettybacon'
end

118
Gemfile.lock Normal file
View File

@ -0,0 +1,118 @@
PATH
remote: .
specs:
cocoapods-binary (0.4.4)
cocoapods (>= 1.5.0, < 2.0)
fourflusher (~> 2.0)
xcpretty (~> 0.3.0)
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
activesupport (4.2.11.1)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
atomos (0.1.3)
bacon (1.2.0)
claide (1.0.2)
cocoapods (1.6.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.6.1)
cocoapods-deintegrate (>= 1.0.2, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.3.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.2.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.8.1, < 2.0)
cocoapods-core (1.6.1)
activesupport (>= 4.0.2, < 6)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
colored2 (3.1.2)
concurrent-ruby (1.1.5)
diff-lcs (1.3)
escape (0.0.4)
fourflusher (2.2.0)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
metaclass (0.0.4)
minitest (5.11.3)
mocha (1.8.0)
metaclass (~> 0.0.1)
mocha-on-bacon (0.2.3)
mocha (>= 0.13.0)
molinillo (0.6.6)
nanaimo (0.2.6)
nap (1.1.0)
netrc (0.11.0)
prettybacon (0.0.2)
bacon (~> 1.2)
rake (12.3.2)
rouge (2.0.7)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-core (3.8.0)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.0)
ruby-macho (1.4.0)
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
xcodeproj (1.8.2)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)
PLATFORMS
ruby
DEPENDENCIES
bacon
bundler (~> 2.0)
cocoapods (= 1.6.1)
cocoapods-binary!
mocha
mocha-on-bacon
prettybacon
rake
rspec
BUNDLED WITH
2.0.1

View File

@ -1,9 +1,13 @@
# cocoapods-binary
<p align="center"><img src="/test/logo.png" width="622"></p>
[![Build Status](https://travis-ci.org/leavez/cocoapods-binary.svg?branch=master)](https://travis-ci.org/leavez/cocoapods-binary)
A CocoaPods plugin to integrate pods in form of prebuilt frameworks, not source code, by adding **just one flag** in podfile. Speed up compiling dramatically.
Good news: Introduction on cocoapods offical site: [Pre-compiling dependencies](http://guides.cocoapods.org/plugins/pre-compiling-dependencies.html) ( NOTE: This plugin is a community work, not official.)
## Why
You may wonder why CocoaPods doesn't have a function to integrate libs in form of binaries, if there are dozens or hundreds of pods in your podfile and compile them for a great many times meaninglessly. Too many source code of libs slow down your compile and the response of IDE (e.g. code completion), and then reduce work efficiency, leaving us time to think about the meaning of life.
@ -63,7 +67,7 @@ If bitcode is needed, add a `enable_bitcode_for_prebuilt_frameworks!` before all
#### Known Issues
- doesn't support watchos now
- dSYM files is missing for dynamic frameworks using this plugin. Walkaround: Don't use this plugin for a release build. Add a if condition with ENV around `plugin 'cocoapods-binary'`
- ~~dSYM files is missing for dynamic frameworks using this plugin. Walkaround: Don't use this plugin for a release build. Add a if condition with ENV around `plugin 'cocoapods-binary'`. [(detail)](https://github.com/leavez/cocoapods-binary/issues/44)~~ (fix in 0.4.2)
## License

View File

@ -13,14 +13,17 @@ Gem::Specification.new do |spec|
spec.homepage = 'https://github.com/leavez/cocoapods-binary'
spec.license = 'MIT'
spec.files = `git ls-files`.split($/).reject{|f| f.start_with? "test/"}
spec.files = `git ls-files`.split($/).reject{|f| f.start_with?("test/") || f.start_with?('demo/')}
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']
spec.add_dependency "cocoapods", ">= 1.5.0", "< 2.0"
spec.add_dependency "fourflusher", "~> 2.0"
spec.add_dependency "xcpretty", "~> 0.3.0"
spec.add_development_dependency 'bundler', '~> 1.3'
spec.add_development_dependency 'bundler', '~> 2.0'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec'
end

2
demo/.bundle/config Normal file
View File

@ -0,0 +1,2 @@
---
BUNDLE_PATH: "./.bundler_cache"

50
demo/.gitignore vendored Normal file
View File

@ -0,0 +1,50 @@
# Created by https://www.gitignore.io/api/xcode,cocoapods
# Edit at https://www.gitignore.io/?templates=xcode,cocoapods
### CocoaPods ###
## CocoaPods GitIgnore Template
# CocoaPods - Only use to conserve bandwidth / Save time on Pushing
# - Also handy if you have a large number of dependant pods
# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE
Pods/
### Xcode ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings
xcuserdata/
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
### Xcode Patch ###
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
!*.xcworkspace/contents.xcworkspacedata
/*.gcno
**/xcshareddata/WorkspaceSettings.xcsettings
# End of https://www.gitignore.io/api/xcode,cocoapods
# the bundler local cache
.bundler_cache/

7
demo/Gemfile Normal file
View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
source "https://rubygems.org"
gem 'cocoapods', '1.6.1'
gem 'cocoapods-binary', :path => "../"
gem 'xcpretty'

89
demo/Gemfile.lock Normal file
View File

@ -0,0 +1,89 @@
PATH
remote: ..
specs:
cocoapods-binary (0.4.4)
cocoapods (>= 1.5.0, < 2.0)
fourflusher (~> 2.0)
xcpretty (~> 0.3.0)
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
activesupport (4.2.11.1)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
atomos (0.1.3)
claide (1.0.2)
cocoapods (1.6.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.6.1)
cocoapods-deintegrate (>= 1.0.2, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.3.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.2.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.8.1, < 2.0)
cocoapods-core (1.6.1)
activesupport (>= 4.0.2, < 6)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
colored2 (3.1.2)
concurrent-ruby (1.1.5)
escape (0.0.4)
fourflusher (2.2.0)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
minitest (5.11.3)
molinillo (0.6.6)
nanaimo (0.2.6)
nap (1.1.0)
netrc (0.11.0)
rouge (2.0.7)
ruby-macho (1.4.0)
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
xcodeproj (1.8.2)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (= 1.6.1)
cocoapods-binary!
xcpretty
BUNDLED WITH
2.0.1

18
demo/Podfile Normal file
View File

@ -0,0 +1,18 @@
source 'https://github.com/CocoaPods/Specs.git'
plugin 'cocoapods-binary'
platform :ios, '11.2'
use_frameworks!
inhibit_all_warnings!
keep_source_code_for_prebuilt_frameworks!
#all_binary!
target 'demo' do
# RxSwift
pod "AFNetworking/Security"
pod "MBKCoreAudioPlayer", :git => '/Users/lea/byte/test/MBKCoreAudioPlayer'
# # Firebase
# pod 'Firebase/Core', :binary => true
# pod 'Firebase/Firestore'

30
demo/Podfile.lock Normal file
View File

@ -0,0 +1,30 @@
PODS:
- AFNetworking/Reachability (3.2.1)
- AFNetworking/Security (3.2.1)
- MBKCoreAudioPlayer (0.1.0):
- AFNetworking/Reachability
DEPENDENCIES:
- AFNetworking/Security
- MBKCoreAudioPlayer (from `/Users/lea/byte/test/MBKCoreAudioPlayer`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- AFNetworking
EXTERNAL SOURCES:
MBKCoreAudioPlayer:
:git: "/Users/lea/byte/test/MBKCoreAudioPlayer"
CHECKOUT OPTIONS:
MBKCoreAudioPlayer:
:commit: 4da6aba01ea48f8ef6c4d45da1eb97ad9ae82205
:git: "/Users/lea/byte/test/MBKCoreAudioPlayer"
SPEC CHECKSUMS:
AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057
MBKCoreAudioPlayer: 996c4ecc9d146598001e0cf9d98fabb6a338888a
PODFILE CHECKSUM: 2cca0929b163692b302f27e4242a12f0c54cd3b6
COCOAPODS: 1.6.1

View File

@ -0,0 +1,569 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
2D9A260E8A0E3144419CB9CC /* Pods_demoTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F95BAE6229AA9F41F56F06E1 /* Pods_demoTests.framework */; };
2E1AEA2ADE0B2C6D0E8CB73C /* BDWebImage_demo.m in Sources */ = {isa = PBXBuildFile; fileRef = 89A7B09D8E1B9A5928206B3D /* BDWebImage_demo.m */; };
3EAFB6B6226E35CC00840968 /* demoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EAFB6B5226E35CC00840968 /* demoTests.swift */; };
7ADC04F6B6AD86B4711FC662 /* Pods_demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0282097ED33E34DF2FB40193 /* Pods_demo.framework */; };
8BC2E4C8225F2B8600EC0609 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BC2E4C7225F2B8600EC0609 /* AppDelegate.swift */; };
8BC2E4CA225F2B8600EC0609 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BC2E4C9225F2B8600EC0609 /* ViewController.swift */; };
8BC2E4D2225F2B8700EC0609 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8BC2E4D0225F2B8700EC0609 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
3EAFB6B8226E35CC00840968 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8BC2E4BC225F2B8600EC0609 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8BC2E4C3225F2B8600EC0609;
remoteInfo = demo;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0282097ED33E34DF2FB40193 /* Pods_demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3EAFB6B3226E35CC00840968 /* demoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = demoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3EAFB6B5226E35CC00840968 /* demoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = demoTests.swift; sourceTree = "<group>"; };
3EAFB6B7226E35CC00840968 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
89A7B09D8E1B9A5928206B3D /* BDWebImage_demo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = BDWebImage_demo.m; sourceTree = "<group>"; };
8BC2E4C4225F2B8600EC0609 /* demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
8BC2E4C7225F2B8600EC0609 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
8BC2E4C9225F2B8600EC0609 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
8BC2E4D1225F2B8700EC0609 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
8BC2E4D3225F2B8700EC0609 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9A8064F1F3E5738D234C80E2 /* Pods-demoTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-demoTests.release.xcconfig"; path = "Target Support Files/Pods-demoTests/Pods-demoTests.release.xcconfig"; sourceTree = "<group>"; };
C55F7BF03CC970F91505F490 /* Pods-demoTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-demoTests.debug.xcconfig"; path = "Target Support Files/Pods-demoTests/Pods-demoTests.debug.xcconfig"; sourceTree = "<group>"; };
E9C2707150376AA5D63E8BAE /* Pods-demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-demo.release.xcconfig"; path = "Target Support Files/Pods-demo/Pods-demo.release.xcconfig"; sourceTree = "<group>"; };
F8A8B289BFEAE54B0D540472 /* Pods-demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-demo.debug.xcconfig"; path = "Target Support Files/Pods-demo/Pods-demo.debug.xcconfig"; sourceTree = "<group>"; };
F95BAE6229AA9F41F56F06E1 /* Pods_demoTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_demoTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
3EAFB6B0226E35CC00840968 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2D9A260E8A0E3144419CB9CC /* Pods_demoTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8BC2E4C1225F2B8600EC0609 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7ADC04F6B6AD86B4711FC662 /* Pods_demo.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
03BCE6F733E8AF8755385CE8 /* Frameworks */ = {
isa = PBXGroup;
children = (
0282097ED33E34DF2FB40193 /* Pods_demo.framework */,
F95BAE6229AA9F41F56F06E1 /* Pods_demoTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
3EAFB6B4226E35CC00840968 /* demoTests */ = {
isa = PBXGroup;
children = (
3EAFB6B5226E35CC00840968 /* demoTests.swift */,
3EAFB6B7226E35CC00840968 /* Info.plist */,
);
path = demoTests;
sourceTree = "<group>";
};
48064E0CABFB2B206E032E3B /* demos */ = {
isa = PBXGroup;
children = (
89A7B09D8E1B9A5928206B3D /* BDWebImage_demo.m */,
);
name = demos;
path = ./demos;
sourceTree = "<group>";
};
8BC2E4BB225F2B8600EC0609 = {
isa = PBXGroup;
children = (
8BC2E4C6225F2B8600EC0609 /* demo */,
3EAFB6B4226E35CC00840968 /* demoTests */,
8BC2E4C5225F2B8600EC0609 /* Products */,
D25B1A678978B02ABFF01D1C /* Pods */,
03BCE6F733E8AF8755385CE8 /* Frameworks */,
);
sourceTree = "<group>";
};
8BC2E4C5225F2B8600EC0609 /* Products */ = {
isa = PBXGroup;
children = (
8BC2E4C4225F2B8600EC0609 /* demo.app */,
3EAFB6B3226E35CC00840968 /* demoTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
8BC2E4C6225F2B8600EC0609 /* demo */ = {
isa = PBXGroup;
children = (
8BC2E4C7225F2B8600EC0609 /* AppDelegate.swift */,
8BC2E4C9225F2B8600EC0609 /* ViewController.swift */,
8BC2E4D0225F2B8700EC0609 /* LaunchScreen.storyboard */,
8BC2E4D3225F2B8700EC0609 /* Info.plist */,
48064E0CABFB2B206E032E3B /* demos */,
);
path = demo;
sourceTree = "<group>";
};
D25B1A678978B02ABFF01D1C /* Pods */ = {
isa = PBXGroup;
children = (
F8A8B289BFEAE54B0D540472 /* Pods-demo.debug.xcconfig */,
E9C2707150376AA5D63E8BAE /* Pods-demo.release.xcconfig */,
C55F7BF03CC970F91505F490 /* Pods-demoTests.debug.xcconfig */,
9A8064F1F3E5738D234C80E2 /* Pods-demoTests.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
3EAFB6B2226E35CC00840968 /* demoTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3EAFB6BC226E35CC00840968 /* Build configuration list for PBXNativeTarget "demoTests" */;
buildPhases = (
67074144CE0F3108E2575310 /* [CP] Check Pods Manifest.lock */,
3EAFB6AF226E35CC00840968 /* Sources */,
3EAFB6B0226E35CC00840968 /* Frameworks */,
3EAFB6B1226E35CC00840968 /* Resources */,
);
buildRules = (
);
dependencies = (
3EAFB6B9226E35CC00840968 /* PBXTargetDependency */,
);
name = demoTests;
productName = demoTests;
productReference = 3EAFB6B3226E35CC00840968 /* demoTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
8BC2E4C3225F2B8600EC0609 /* demo */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8BC2E4E1225F2B8800EC0609 /* Build configuration list for PBXNativeTarget "demo" */;
buildPhases = (
4A7278B702427200DBDC45CB /* [CP] Check Pods Manifest.lock */,
8BC2E4C0225F2B8600EC0609 /* Sources */,
8BC2E4C1225F2B8600EC0609 /* Frameworks */,
8BC2E4C2225F2B8600EC0609 /* Resources */,
27E132FE722A29856F619A3D /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = demo;
productName = demo;
productReference = 8BC2E4C4225F2B8600EC0609 /* demo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
8BC2E4BC225F2B8600EC0609 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1020;
LastUpgradeCheck = 1020;
TargetAttributes = {
3EAFB6B2226E35CC00840968 = {
CreatedOnToolsVersion = 10.2.1;
TestTargetID = 8BC2E4C3225F2B8600EC0609;
};
8BC2E4C3225F2B8600EC0609 = {
CreatedOnToolsVersion = 10.2;
};
};
binary = binary;
};
buildConfigurationList = 8BC2E4BF225F2B8600EC0609 /* Build configuration list for PBXProject "demo" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 8BC2E4BB225F2B8600EC0609;
productRefGroup = 8BC2E4C5225F2B8600EC0609 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
8BC2E4C3225F2B8600EC0609 /* demo */,
3EAFB6B2226E35CC00840968 /* demoTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
3EAFB6B1226E35CC00840968 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
8BC2E4C2225F2B8600EC0609 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8BC2E4D2225F2B8700EC0609 /* LaunchScreen.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
27E132FE722A29856F619A3D /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-demo/Pods-demo-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
"${BUILT_PRODUCTS_DIR}/MBKCoreAudioPlayer/MBKCoreAudioPlayer.framework",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBKCoreAudioPlayer.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-demo/Pods-demo-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
4A7278B702427200DBDC45CB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-demo-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
67074144CE0F3108E2575310 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-demoTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
3EAFB6AF226E35CC00840968 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3EAFB6B6226E35CC00840968 /* demoTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8BC2E4C0225F2B8600EC0609 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8BC2E4CA225F2B8600EC0609 /* ViewController.swift in Sources */,
8BC2E4C8225F2B8600EC0609 /* AppDelegate.swift in Sources */,
2E1AEA2ADE0B2C6D0E8CB73C /* BDWebImage_demo.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
3EAFB6B9226E35CC00840968 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8BC2E4C3225F2B8600EC0609 /* demo */;
targetProxy = 3EAFB6B8226E35CC00840968 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
8BC2E4D0225F2B8700EC0609 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
8BC2E4D1225F2B8700EC0609 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
3EAFB6BA226E35CC00840968 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C55F7BF03CC970F91505F490 /* Pods-demoTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = demoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods-binary.demoTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/demo.app/demo";
};
name = Debug;
};
3EAFB6BB226E35CC00840968 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9A8064F1F3E5738D234C80E2 /* Pods-demoTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = demoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods-binary.demoTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/demo.app/demo";
};
name = Release;
};
8BC2E4DF225F2B8800EC0609 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
8BC2E4E0225F2B8800EC0609 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
8BC2E4E2225F2B8800EC0609 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F8A8B289BFEAE54B0D540472 /* Pods-demo.debug.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = demo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
8BC2E4E3225F2B8800EC0609 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = E9C2707150376AA5D63E8BAE /* Pods-demo.release.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = demo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
3EAFB6BC226E35CC00840968 /* Build configuration list for PBXNativeTarget "demoTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3EAFB6BA226E35CC00840968 /* Debug */,
3EAFB6BB226E35CC00840968 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8BC2E4BF225F2B8600EC0609 /* Build configuration list for PBXProject "demo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8BC2E4DF225F2B8800EC0609 /* Debug */,
8BC2E4E0225F2B8800EC0609 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8BC2E4E1225F2B8800EC0609 /* Build configuration list for PBXNativeTarget "demo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8BC2E4E2225F2B8800EC0609 /* Debug */,
8BC2E4E3225F2B8800EC0609 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 8BC2E4BC225F2B8600EC0609 /* Project object */;
}

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:demo.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,53 @@
//
// AppDelegate.swift
// demo
//
// Created by Leavez on 2019/04/16.
// Copyright © 2019 binary. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let viewController = ViewController(nibName: nil, bundle: nil)
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = viewController
self.window = window
window.makeKeyAndVisible()
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

43
demo/demo/Info.plist Normal file
View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,21 @@
//
// ViewController.swift
// demo
//
// Created by Leavez on 2019/04/16.
// Copyright © 2019 binary. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .white
}
}

View File

@ -0,0 +1,16 @@
// this is a demo for usage
#import <UIKit/UIKit.h>
#import <Masonry/Masonry.h>
void masonry_demo() {
UIView *parent_view = [UIView new];
UIView *view1 = [UIView new];
[parent_view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(0);
}];
}

22
demo/demoTests/Info.plist Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,32 @@
//
// demoTests.swift
// demoTests
//
// Created by Gao on 2019/4/23.
//
import XCTest
class demoTests: XCTestCase {
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}

View File

@ -1,7 +1,10 @@
require_relative 'helper/podfile_options'
require_relative 'extensions/podfile_options'
require_relative 'helper/feature_switches'
require_relative 'helper/prebuild_sandbox'
require_relative 'extensions/prebuild_sandbox'
require_relative 'extensions/installer_prebuild_targets'
require_relative 'helper/passer'
require_relative 'helper/names'
require_relative 'helper/target_checker'
# NOTE:
@ -24,14 +27,11 @@ module Pod
# make a symlink to target folder
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sanbox)
real_file_folder = prebuild_sandbox.framework_folder_path_for_pod_name(self.name)
target_folder = standard_sanbox.pod_dir(self.name)
target_folder.rmtree if target_folder.exist?
target_folder.mkdir
# make a relatvie symbol link for all children
# if spec used in multiple platforms, it may return multiple paths
target_names = prebuild_sandbox.existed_target_names_for_pod_name(self.name)
def walk(path, &action)
return unless path.exist?
path.children.each do |child|
result = action.call(child, &action)
if child.directory?
@ -50,31 +50,51 @@ module Pod
target = target_folder + source.relative_path_from(basefolder)
make_link(source, target)
end
target_names.each do |name|
# symbol link copy all substructure
walk(real_file_folder) do |child|
source = child
# only make symlink to file and `.framework` folder
if child.directory? and [".framework", ".dSYM"].include? child.extname
mirror_with_symlink(source, real_file_folder, target_folder)
next false # return false means don't go deeper
elsif child.file?
mirror_with_symlink(source, real_file_folder, target_folder)
next true
else
next true
# symbol link copy all substructure
real_file_folder = prebuild_sandbox.framework_folder_path_for_target_name(name)
# If have only one platform, just place int the root folder of this pod.
# If have multiple paths, we use a sperated folder to store different
# platform frameworks. e.g. AFNetworking/AFNetworking-iOS/AFNetworking.framework
target_folder = standard_sanbox.pod_dir(self.name)
if target_names.count > 1
target_folder += real_file_folder.basename
end
end
target_folder.rmtree if target_folder.exist?
target_folder.mkpath
# symbol link copy resource for static framework
hash = Prebuild::Passer.resources_to_copy_for_static_framework || {}
path_objects = hash[self.name]
if path_objects != nil
path_objects.each do |object|
make_link(object.real_file_path, object.target_file_path)
walk(real_file_folder) do |child|
source = child
# only make symlink to file and `.framework` folder
if child.directory? and [".framework", ".dSYM"].include? child.extname
mirror_with_symlink(source, real_file_folder, target_folder)
next false # return false means don't go deeper
elsif child.file?
mirror_with_symlink(source, real_file_folder, target_folder)
next true
else
next true
end
end
end
end
# symbol link copy resource for static framework
hash = Prebuild::Passer.resources_to_copy_for_static_framework || {}
path_objects = hash[name]
if path_objects != nil
path_objects.each do |object|
make_link(object.real_file_path, object.target_file_path)
end
end
end # of for each
end # of method
end
end
@ -95,7 +115,7 @@ module Pod
changes = Pod::Prebuild::Passer.prebuild_pods_changes
updated_names = []
if changes == nil
updated_names = PrebuildSandbox.from_standard_sandbox(self.sandbox).exsited_framework_names
updated_names = PrebuildSandbox.from_standard_sandbox(self.sandbox).exsited_framework_pod_names
else
added = changes.added
changed = changes.changed
@ -127,16 +147,37 @@ module Pod
# call original
old_method2.bind(self).()
# ...
# ...
# ...
# after finishing the very complex orginal function
# check the pods
# Although we have did it in prebuild stage, it's not sufficient.
# Same pod may appear in another target in form of source code.
# Prebuild.check_one_pod_should_have_only_one_target(self.prebuild_pod_targets)
self.validate_every_pod_only_have_one_form
# check the prebuilt targets
targets = self.prebuild_pod_targets
targets_have_different_platforms = targets.select {|t| t.pod_name != t.name }
# prepare
cache = []
if targets_have_different_platforms.count > 0
names = targets_have_different_platforms.map(&:pod_name)
STDERR.puts "[!] Binary doesn't support pods who integrate in 2 or more platforms simultaneously: #{names}".red
exit
def add_vendered_framework(spec, platform, added_framework_file_path)
if spec.attributes_hash[platform] == nil
spec.attributes_hash[platform] = {}
end
vendored_frameworks = spec.attributes_hash[platform]["vendored_frameworks"] || []
vendored_frameworks = [vendored_frameworks] if vendored_frameworks.kind_of?(String)
vendored_frameworks += [added_framework_file_path]
spec.attributes_hash[platform]["vendored_frameworks"] = vendored_frameworks
end
def empty_source_files(spec)
spec.attributes_hash["source_files"] = []
["ios", "watchos", "tvos", "osx"].each do |plat|
if spec.attributes_hash[plat] != nil
spec.attributes_hash[plat]["source_files"] = []
end
end
end
@ -144,41 +185,36 @@ module Pod
prebuilt_specs = (specs.select do |spec|
self.prebuild_pod_names.include? spec.root.name
end)
# make sturcture to fast get target by name
name_to_target_hash = self.pod_targets.reduce({}) do |sum, target|
sum[target.name] = target
sum
end
prebuilt_specs.each do |spec|
# `spec` may be a subspec, so we use the root's name
# `spec` may be a subspec, so we use the root's name
p spec.name
p spec.target_definition
p spec.target_definition.
root_name = spec.root.name
#TODO target_name pod_name!!!!
target = name_to_target_hash[root_name]
next if Prebuild::Passer.target_names_to_skip_integration_framework.include? target.pod_name
next if Prebuild::Passer.target_names_to_skip_integration_framework.include? target.name
# use the prebuilt framework
original_vendored_frameworks = spec.attributes_hash["vendored_frameworks"] || []
if original_vendored_frameworks.kind_of?(String)
original_vendored_frameworks = [original_vendored_frameworks]
end
original_vendored_frameworks += [target.framework_name]
spec.attributes_hash["vendored_frameworks"] = original_vendored_frameworks
spec.attributes_hash["source_files"] = []
# to remove the resurce bundle target.
# When specify the "resource_bundles" in podspec, xcode will generate a bundle
# target after pod install. But the bundle have already built when the prebuit
# phase and saved in the framework folder. We will treat it as a normal resource
# file.
# https://github.com/leavez/cocoapods-binary/issues/29
if spec.attributes_hash["resource_bundles"]
bundle_names = spec.attributes_hash["resource_bundles"].keys
spec.attributes_hash["resource_bundles"] = nil
spec.attributes_hash["resources"] ||= []
spec.attributes_hash["resources"] += bundle_names.map{|n| n+".bundle"}
p ",,", target.target_definition
# Use the prebuild framworks as vendered frameworks
# get_corresponding_targets
targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
targets.each do |target|
# the framework_file_path rule is decided when `install_for_prebuild`,
# as to compitable with older version and be less wordy.
framework_file_path = target.framework_name
framework_file_path = target.name + "/" + framework_file_path if targets.count > 1
add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
end
# Clean the source files
# we just add the prebuilt framework to specific platform and set no source files
# for all platform, so it doesn't support the sence that 'a pod perbuild for one
# platform and not for another platform.'
empty_source_files(spec)
# to remove the resurce bundle target.
# When specify the "resource_bundles" in podspec, xcode will generate a bundle
@ -194,7 +230,8 @@ module Pod
end
# to avoid the warning of missing license
spec.attributes_hash["license"] = {}
spec.attributes_hash["license"] = {}
end
end

View File

@ -1,5 +1,5 @@
# encoding: UTF-8
require_relative 'helper/podfile_options'
require_relative 'extensions/podfile_options'
require_relative 'tool/tool'
module Pod
@ -24,6 +24,37 @@ module Pod
DSL.dont_remove_source_code = true
end
# Add custom xcodebuild option to the prebuilding action
#
# You may use this for your special demands. For example: the default archs in dSYMs
# of prebuilt frameworks is 'arm64 armv7 x86_64', and no 'i386' for 32bit simulator.
# It may generate a warning when building for a 32bit simulator. You may add following
# to your podfile
#
# ` set_custom_xcodebuild_options_for_prebuilt_frameworks :simulator => "ARCHS=$(ARCHS_STANDARD)" `
#
# Another example to disable the generating of dSYM file:
#
# ` set_custom_xcodebuild_options_for_prebuilt_frameworks "DEBUG_INFORMATION_FORMAT=dwarf"`
#
#
# @param [String or Hash] options
#
# If is a String, it will apply for device and simulator. Use it just like in the commandline.
# If is a Hash, it should be like this: { :device => "XXXXX", :simulator => "XXXXX" }
#
def set_custom_xcodebuild_options_for_prebuilt_frameworks(options)
if options.kind_of? Hash
DSL.custom_build_options = [ options[:device] ] unless options[:device].nil?
DSL.custom_build_options_simulator = [ options[:simulator] ] unless options[:simulator].nil?
elsif options.kind_of? String
DSL.custom_build_options = [options]
DSL.custom_build_options_simulator = [options]
else
raise "Wrong type."
end
end
private
class_attr_accessor :prebuild_all
prebuild_all = false
@ -33,13 +64,21 @@ module Pod
class_attr_accessor :dont_remove_source_code
dont_remove_source_code = false
class_attr_accessor :custom_build_options
class_attr_accessor :custom_build_options_simulator
self.custom_build_options = []
self.custom_build_options_simulator = []
end
end
end
Pod::HooksManager.register('cocoapods-binary', :pre_install) do |installer_context|
require_relative 'data_flow'
require_relative 'helper/context'
require_relative 'helper/feature_switches'
if Pod.is_prebuild_stage
next
end
@ -48,36 +87,38 @@ Pod::HooksManager.register('cocoapods-binary', :pre_install) do |installer_conte
# check user_framework is on
podfile = installer_context.podfile
podfile.target_definition_list.each do |target_definition|
next if target_definition.prebuild_framework_names.empty?
next if target_definition.prebuild_framework_pod_names.empty?
if not target_definition.uses_frameworks?
STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
exit
end
end
# -- step 1: prebuild framework ---
# Execute a sperated pod install, to generate targets for building framework,
# then compile them to framework files.
require_relative 'helper/prebuild_sandbox'
require_relative 'extensions/prebuild_sandbox'
require_relative 'Prebuild'
Pod::UI.puts "🚀 Prebuild frameworks"
# Fetch original installer (which is running this pre-install hook) options,
# then pass them to our installer to perform update if needed
# Looks like this is the most appropriate way to figure out that something should be updated
update = nil
repo_update = nil
include ObjectSpace
ObjectSpace.each_object(Pod::Installer) { |installer|
update = installer.update
repo_update = installer.repo_update
}
# control features
Pod::Prebuild::Context.in_prebuild_stage = true
Pod.is_prebuild_stage = true
Pod::Podfile::DSL.enable_prebuild_patch true # enable sikpping for prebuild targets
Pod::Installer.force_disable_integration true # don't integrate targets
@ -89,7 +130,7 @@ Pod::HooksManager.register('cocoapods-binary', :pre_install) do |installer_conte
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)
# get the podfile for prebuild
prebuild_podfile = Pod::Podfile.from_ruby(podfile.defined_in_file)
prebuild_podfile = Pod::Podfile.from_file(podfile.defined_in_file)
# install
lockfile = installer_context.lockfile
@ -105,11 +146,13 @@ Pod::HooksManager.register('cocoapods-binary', :pre_install) do |installer_conte
# reset the environment
Pod::Prebuild::Context.in_prebuild_stage = false
Pod.is_prebuild_stage = false
Pod::Installer.force_disable_integration false
Pod::Podfile::DSL.enable_prebuild_patch false
Pod::Config.force_disable_write_lockfile false
Pod::Installer.disable_install_complete_message false
Pod::UserInterface.warnings = [] # clean the warning in the prebuild step, it's duplicated.
# -- step 2: pod install ---

View File

@ -1,11 +1,141 @@
require_relative 'rome/build_framework'
require_relative 'helper/filter_for_prebuild_project'
require_relative 'helper/passer'
require_relative 'helper/target_checker'
require_relative 'helper/context'
require_relative 'extensions/prebuild_sandbox'
require_relative 'extensions/installer_prebuild_targets'
require_relative 'data_flow'
# patch prebuild ability
module Pod
class Installer
### Make the prebuild xcode project only contain prebuild pod
###
do_before_method(:install!, only_when: Pod::Prebuild.prebuild_stage_condition) do
podfile = self.podfile
filter_method = Prebuild::DataFlow.instance.pods_filter_strategy(podfile)
# modify the podfile in-place
podfile.target_definition_list.each do |target_definition|
# pod dependency
values = target_definition.send(:get_hash_value, 'dependencies')
next if values.nil?
values = values.select do |v|
pod = nil
if v.kind_of?(Hash)
pod = v.keys.first
elsif v.kind_of?(String)
pod = v
else
raise "unexpect type: #{v.inspect}"
end
root_pod = Specification.root_name(pod)
filter_method.call(root_pod)
end
# modify the data directly
target_definition.send(:set_hash_value, 'dependencies', values)
# podspec_dependencies
# TODO
end
end
### SPECIAL HANDLE: redo install when missing dependency requirements ###
###
#
# There's a flow in the current prebuild pod project generating design. It
# just ignore the pod defined in the podfile if it's binary flag is false.
# For most cases, it works fine. But when a pod is off while it's depended
# by another binary pod, it will lose the info specified in podfile.
#
# @see prebuild_spec.rb: search for 'doc_anchor'
#
# To solve this, here's a retry mechanism. If we check out some pods are in
# this case, we stop the current installing and do installing again, while,
# for the second time, preventing the missing pods from filtering out.
# Only be true when in prebuild stage AND config is on
on_prebuild_stage_and_config_on = Proc.new{ Prebuild.prebuild_stage_condition.call } #TODO config
do_before_method(:install!, only_when: on_prebuild_stage_and_config_on) do
podfile.original_dependencies = podfile.dependencies # save for later use
end
# Check if have missing dependencies, and trigger a retry if needed.
do_after_method(:resolve_dependencies, only_when: on_prebuild_stage_and_config_on) do |*args|
assert podfile.original_dependencies != nil, 'Did you forget to set the value?'
names_with_missing_requirements = Prebuild::DataFlow.instance.check_dependency_setting_missing(
self.podfile, self.podfile.original_dependencies, self.pod_targets)
# use raise to break the normal program flow
if !names_with_missing_requirements.empty?
e = PrebuildMissingRequirementError.new
e.missing_pod_names = names_with_missing_requirements.to_a
raise e
end
end
# Implement the retry mechanism
modify_method(:install!, only_when: on_prebuild_stage_and_config_on) do |original, args|
last_missing_pod_names, retry_count = @retry_args
@retry_args = nil # clean
begin
# call original
original.(*args)
rescue PrebuildMissingRequirementError => e
retry_count ||= 0
last_missing_pod_names ||= []
all_missing_names = e.missing_pod_names + last_missing_pod_names
if retry_count >= 10
raise "Too many retry for prebuild."
end
Prebuild::DataFlow.instance.supply_missing_names(all_missing_names)
installer = regenerate_installer
# install! method cannot pass parameters, so we just pass it by instance variable.
installer.instance_variable_set(:@retry_args, [all_missing_names, retry_count + 1])
installer.install!
end
end
private def regenerate_original_podfile
assert @podfile.defined_in_file != nil
Podfile.from_file(@podfile.defined_in_file)
end
private def regenerate_installer
podfile = self.regenerate_original_podfile
installer = Pod::Installer.new(@sandbox, podfile, @lockfile)
installer.installation_options = self.installation_options
installer
end
Podfile.class_eval do
attr_accessor :original_dependencies # copy of dependencies before modify podfile
end
class PrebuildMissingRequirementError < StandardError
attr_accessor :missing_pod_names
end
### Prebuild Install Cache
###
private
def local_manifest
@ -43,11 +173,9 @@ module Pod
unchanged = changes.unchanged
deleted = changes.deleted
unchange_framework_names = (added + unchanged)
exsited_framework_names = sandbox.exsited_framework_names
exsited_framework_pod_names = sandbox.exsited_framework_pod_names
missing = unchanged.select do |pod_name|
not exsited_framework_names.include?(pod_name)
not exsited_framework_pod_names.include?(pod_name)
end
needed = (added + changed + deleted + missing)
@ -58,7 +186,7 @@ module Pod
# The install method when have completed cache
def install_when_cache_hit!
# just print log
self.sandbox.exsited_framework_names.each do |name|
self.sandbox.exsited_framework_target_names.each do |name|
UI.puts "Using #{name}"
end
end
@ -82,24 +210,25 @@ module Pod
deleted = changes.deleted
existed_framework_folder.mkdir unless existed_framework_folder.exist?
exsited_framework_names = sandbox.exsited_framework_names
exsited_framework_pod_names = sandbox.exsited_framework_pod_names
# additions
missing = unchanged.select do |pod_name|
not exsited_framework_names.include?(pod_name)
not exsited_framework_pod_names.include?(pod_name)
end
root_names_to_update = (added + changed + missing)
# transform names to targets
name_to_target_hash = self.pod_targets.reduce({}) do |sum, target|
sum[target.name] = target
sum
end
targets = root_names_to_update.map do |root_name|
name_to_target_hash[root_name]
end || []
cache = []
targets = root_names_to_update.map do |pod_name|
tars = Pod.fast_get_targets_for_pod_name(pod_name, self.pod_targets, cache)
if tars.nil? || tars.empty?
raise "There's no target named (#{pod_name}) in Pod.xcodeproj.\n #{self.pod_targets.map(&:name)}" if tars.nil?
end
tars
end.flatten
# add the dendencies
dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
@ -111,22 +240,37 @@ module Pod
targets = targets.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
# build!
Pod::UI.puts "Prebuild frameworks (total #{targets.count})"
Pod::Prebuild.remove_build_dir(sandbox_path)
targets.each do |target|
next unless target.should_build?
if !target.should_build?
UI.puts "Prebuilding #{target.label}"
next
end
output_path = sandbox.framework_folder_path_for_pod_name(target.name)
output_path = sandbox.framework_folder_path_for_target_name(target.name)
output_path.mkpath unless output_path.exist?
Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled)
Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator)
# save the resource paths for later installing
if target.static_framework? and !target.resource_paths.empty?
framework_path = output_path + target.framework_name
standard_sandbox_path = sandbox.standard_sanbox_path
path_objects = target.resource_paths.map do |path|
resources = begin
if Pod::VERSION.start_with? "1.5"
target.resource_paths
else
# resource_paths is Hash{String=>Array<String>} on 1.6 and above
# (use AFNetworking to generate a demo data)
# https://github.com/leavez/cocoapods-binary/issues/50
target.resource_paths.values.flatten
end
end
raise "Wrong type: #{resources}" unless resources.kind_of? Array
path_objects = resources.map do |path|
object = Prebuild::Passer::ResourcePath.new
object.real_file_path = framework_path + File.basename(path)
object.target_file_path = path.gsub('${PODS_ROOT}', standard_sandbox_path.to_s) if path.start_with? '${PODS_ROOT}'
@ -135,6 +279,7 @@ module Pod
end
Prebuild::Passer.resources_to_copy_for_static_framework[target.name] = path_objects
end
end
Pod::Prebuild.remove_build_dir(sandbox_path)
@ -142,12 +287,12 @@ module Pod
# copy vendored libraries and frameworks
targets.each do |target|
root_path = self.sandbox.pod_dir(target.name)
target_folder = sandbox.framework_folder_path_for_pod_name(target.name)
target_folder = sandbox.framework_folder_path_for_target_name(target.name)
# If target shouldn't build, we copy all the original files
# This is for target with only .a and .h files
if not target.should_build?
Prebuild::Passer.target_names_to_skip_integration_framework << target.pod_name
Prebuild::Passer.target_names_to_skip_integration_framework << target.name
FileUtils.cp_r(root_path, target_folder, :remove_destination => true)
next
end
@ -165,15 +310,20 @@ module Pod
end
end
end
# save the pod_name for prebuild framwork in sandbox
targets.each do |target|
sandbox.save_pod_name_for_target target
end
# Remove useless files
# remove useless pods
all_needed_names = self.pod_targets.map(&:name).uniq
useless_names = sandbox.exsited_framework_names.reject do |name|
useless_target_names = sandbox.exsited_framework_target_names.reject do |name|
all_needed_names.include? name
end
useless_names.each do |name|
path = sandbox.framework_folder_path_for_pod_name(name)
useless_target_names.each do |name|
path = sandbox.framework_folder_path_for_target_name(name)
path.rmtree if path.exist?
end
@ -196,8 +346,8 @@ module Pod
end
# patch the post install hook
old_method2 = instance_method(:run_plugins_post_install_hooks)
define_method(:run_plugins_post_install_hooks) do

View File

@ -0,0 +1,215 @@
require_relative 'tool/tool'
# # BACKGROUND
#
# ## ABOUT NAMES
#
# There are many kinds of name in cocoapods. Two main names are widely used in this plugin:
#
# - root_spec.name (spec.root_name, target.pod_name):
# aka "pod_name"
# the name we use in podfile. the concept.
#
# - target.name:
# aka "target_name"
# the name of the final target in xcode project. The final real thing.
#
# One pod may have multiple targets in xcode project, due to one pod can be used in multiple
# platform simultaneously. So one `root_spec.name` may have multiple corresponding `target.name`s.
# Therefore, map a spec to/from targets is a little complicated. It's one to many relation (spec -> targets).
#
# Despite the multiple platform, there's another situation to have multiple target, subspec.
# If 2 targets of same platform in podfile all have Pod A, one have 'A/sub1', 'A/sub2', the other
# have 'A/sub1', there will be 2 pod targets in Pod.xcodeproj: A-sub1-sub2, A-sub1
#
#
# # OUR RULES
#
# For simplicity, we have set several rules:
#
# 1. Any part of the pod is set to binary, all the pod should be binary
# 2. Dependencies of a binary is also binary be default, except disabled explicitly.
# 3. Don't support for the different subspecs lead to multiple pod targets case.
#
# For the first rule, for example, a subspec is binary while others are not, or in one target is
# binary while in another is not. All the source code in this pod should be binary)
#
# For the rule 3, it's a limitation. Solving it is not deserved as subspecs may contain duplicated
# contents. It may happens when
#
#
module Pod
class Prebuild
# This class provides core data flow manipulations, illustrating
# how 'pod_name', 'target' and 'spec' transfer between each other.
#
# We just process the model data here, no real action.
class DataFlow
include Singleton
################ 1 filter the podfile for prebuild ################
# Filter the dependencies pod in podfile, only keep the prebuild ones.
# This method return a Proc, which can be use to modify the podfile.
#
# We do use this filter method, rather than just hack the pod function,
# because the latter can not handle subspec of different binary state.
#
# @param [Podfile] podfile
# @return [Proc(String(pod_name) -> Bool)]
def pods_filter_strategy(podfile)
should_include = podfile.explicitly_prebuild_pod_names
should_include += self.missing_names unless self.missing_names.nil?
Proc.new do |pod_name|
should_include.include? pod_name
end
end
# Get the prebuild targets, which will be transformed to binary framework finally.
# (It doesn't means the target will actually perform a build action, as there may be a cache.)
#
# @param [Podfile] podfile
# @param [Array<PodTargets>] pod_targets_in_prebuild_project
# The pod_targets of prebuild project, which have been filtered by `podfile_dependency_filter_strategy`.
# It should contain the targets to prebuild and it's dependencies.
#
# @return [Array<PodTarget>]
def get_prebuild_targets(podfile, pod_targets_in_prebuild_project)
should_exclude = podfile.explicitly_not_prebuild_pod_names
# There may be different settings for different targets, so we just let the true be the first priority.
should_exclude -= podfile.explicitly_prebuild_pod_names
pod_targets_in_prebuild_project.reject do |target|
should_exclude.include?(target.pod_name) || target.specs.any?{|s| s.root.local?}
end
end
################ 2 generating project and build ###################
# @see 'SPECIAL HANDLE' in Prebuild.rb
# @param [Podfile] podfile
# @param [Array<Dependency>] original_dependencies
# @param [Array<PodTargets>] real_generated_targets
def check_dependency_setting_missing(podfile, original_dependencies, real_generated_targets)
explicity_dependecies_pod_names = original_dependencies.map(&:root_name)
filter_method = self.pods_filter_strategy(podfile)
ignored_pod_names = Set.new explicity_dependecies_pod_names.reject(&filter_method)
real_generated_pod_names = Set.new(real_generated_targets.map(&:pod_name))
missing_requirements = ignored_pod_names.intersection(real_generated_pod_names)
missing_requirements
end
# @return [Array<String>]
attr_accessor :missing_names
def supply_missing_names(pod_names)
self.missing_names = pod_names
end
# saved all the prebuilt pod names here
# @return [Array<String>]
private attr_accessor :prebuilt_pod_names
# saved all the prebuilt target names
# @return [Array<String>]
private attr_accessor :prebuild_target_names
# Save the names for later use (integration step)
# @param [Array<PodTarget>] pod_targets
# @return [Void]
def save_prebuilt_names(pod_targets)
self.prebuilt_pod_names = pod_targets.map(&:pod_name).uniq
self.prebuild_target_names = pod_targets.map(&:name)
end
################ 3 output frameworks ##############################
class TargetPersistenceInfo
class AdditionalInfo
attr_accessor :target_name # [String]
attr_accessor :corresponding_pod_name # [String]
attr_accessor :target_identifier # TODO
end
# meta info
attr_accessor :target_name # [String]
attr_accessor :additional_info # [AdditionalInfo]
# paths
attr_accessor :persistence_root_folder # [Pathname]
attr_accessor :framework_file_path # [Pathname]
attr_accessor :other_resources_folder # [Pathname]
attr_accessor :additional_info_path # [Pathname]
end
# Generate the persistence meta info for a target, which will be
# used in saving framework.
#
# @param [PodTarget] target
# @param [PrebuildSandbox] prebuild_sandbox
# @return [TargetPersistenceInfo]
def persistence_info_for_target(target, prebuild_sandbox)
info = TargetPersistenceInfo.new
info.additional_info = TargetPersistenceInfo::AdditionalInfo.new.tap do |i|
i.target_name = target.name
i.corresponding_pod_name = target.pod_name
# TODO
# i.target_identifier
end
target_name = target.name
info.target_name = target_name
info.persistence_root_folder = prebuild_sandbox.generate_framework_path + target_name
info.framework_file_path =
end
########### 4 install built frameworks (Integration Stage) #####
# Get all the prebuilt targets saved in the Pod/_Prebuild folder
#
# @return [Array<TargetPersistenceInfo>]
def prebuilt_targets_infos
end
################ 5 modify specs ################################
class SpecModification
attr_accessor :spec
attr_accessor :framework_path
attr_accessor :framework_path_by_platform
end
# Generate the meta info for modify specs
#
# @param [Array<Specification>] all_specs
# @return [Array<SpecModification>]
def get_spec_modification_infos(all_specs)
end
end
end
end

View File

@ -0,0 +1,50 @@
require_relative '../data_flow'
require_relative '../helper/context'
module Pod
class Installer
# Get the all the prebuild targets
# It can only be called at the prebuild installer
#
# @return [Array<PodTarget>]
def prebuild_pod_targets
assert Prebuild::Context.in_prebuild_stage
@prebuild_pod_targets ||= (
Prebuild::DataFlow.instance.get_prebuild_targets(self.podfile, self.pod_targets)
)
end
# the root names who needs prebuild, including dependency pods.
def prebuild_pod_names
@prebuild_pod_names ||= self.__prebuild_pod_targets.map(&:pod_name)
end
def validate_every_pod_only_have_one_form
multi_targets_pods = self.pod_targets.group_by do |t|
t.pod_name
end.select do |k, v|
v.map{|t| t.platform.name }.count > 1
end
multi_targets_pods = multi_targets_pods.reject do |name, targets|
contained = targets.map{|t| self.__prebuild_pod_targets.include? t }
contained.uniq.count == 1 # all equal
end
return if multi_targets_pods.empty?
warnings = "One pod can only be prebuilt or not prebuilt. These pod have different forms in multiple targets:\n"
warnings += multi_targets_pods.map{|name, targets| " #{name}: #{targets.map{|t|t.platform.name}}"}.join("\n")
raise Informative, warnings
end
end
end

View File

@ -0,0 +1,114 @@
module Pod
class Prebuild
def self.keyword
:binary
end
end
class Podfile
class TargetDefinition
## --- option for setting using prebuild framework ---
def parse_prebuild_framework(name, requirements)
options = requirements.last
return requirements unless options.is_a?(Hash)
pod_name = Specification.root_name(name)
should_prebuild = options.delete(Prebuild.keyword)
raise Informative, "pod '#{name}', :binary => #{should_prebuild}, should be Bool" unless [true, false, nil].include?(should_prebuild)
if should_prebuild != nil
set_prebuild_for_pod(pod_name, should_prebuild)
else
if Pod::Podfile::DSL.prebuild_all
set_prebuild_for_pod(pod_name, true)
else
# do nothing
end
end
requirements.pop if options.empty?
end
def set_prebuild_for_pod(pod_name, should_prebuild)
if should_prebuild == true
@prebuild_framework_pod_names ||= []
@prebuild_framework_pod_names.push pod_name
else
@should_not_prebuild_framework_pod_names ||= []
@should_not_prebuild_framework_pod_names.push pod_name
end
end
def prebuild_framework_pod_names(inherent_parent: true)
names = @prebuild_framework_pod_names || []
if inherent_parent && parent != nil and parent.kind_of? TargetDefinition
names += parent.prebuild_framework_pod_names
end
names
end
def should_not_prebuild_framework_pod_names(inherent_parent: true)
names = @should_not_prebuild_framework_pod_names || []
if inherent_parent && parent != nil and parent.kind_of?(TargetDefinition)
names += parent.should_not_prebuild_framework_pod_names
end
names
end
# ---- patch method ----
# We want modify `store_pod` method, but it's hard to insert a line in the
# implementation. So we patch a method called in `store_pod`.
old_method = instance_method(:parse_inhibit_warnings)
define_method(:parse_inhibit_warnings) do |name, requirements|
parse_prebuild_framework(name, requirements)
old_method.bind(self).(name, requirements)
end
end
end
class Podfile
public
# The pod names that set to binary explicitly in podfile
#
# if `all_binary!` is on, a pod without explicit binary flag will also be included.
# A implicit dependency of a binary pod is not in this.
#
# @return [Set<String>]
def explicitly_prebuild_pod_names
@explicitly_prebuild_pod_names ||= begin
target_definitions = self.target_definition_list
all_explicit_pod_names = target_definitions.map do |td|
td.prebuild_framework_pod_names(inherent_parent: false)
end.flatten
Set.new(all_explicit_pod_names)
end
end
# The pod names that set to not binary in podfile explicitly, i.e. pods with
# `:binary => false`
#
# @return [Set<String>]
def explicitly_not_prebuild_pod_names
@explicitly_not_prebuild_pod_names = begin
names = self.target_definition_list.map do |td|
td.should_not_prebuild_framework_pod_names(inherent_parent: false)
end.flatten
Set.new(names)
end
end
end
end

View File

@ -0,0 +1,87 @@
require_relative "../helper/names"
module Pod
class PrebuildSandbox < Sandbox
# [String] standard_sandbox_path
def self.from_standard_sanbox_path(path)
prebuild_sandbox_path = Pathname.new(path).realpath + "_Prebuild"
self.new(prebuild_sandbox_path)
end
def self.from_standard_sandbox(sandbox)
self.from_standard_sanbox_path(sandbox.root)
end
# --
def standard_sanbox_path
self.root.parent
end
def generate_framework_path
@generate_framework_path ||= (self.root + "GeneratedFrameworks")
end
# ---
# # Generate the persistence path for target
# # @param [String] target_name
# # @return [Pathname]
# def persistence_path_for_target_named(target_name)
# self.generate_framework_path + target_name
# end
# @param name [String] pass the target.name (may containing platform suffix)
# @return [Pathname] the folder containing the framework file.
def framework_folder_path_for_target_name(name)
self.generate_framework_path + name
end
def exsited_framework_target_names
exsited_framework_name_pairs.map {|pair| pair[0]}.uniq
end
def exsited_framework_pod_names
exsited_framework_name_pairs.map {|pair| pair[1]}.uniq
end
def existed_target_names_for_pod_name(pod_name)
exsited_framework_name_pairs.select {|pair| pair[1] == pod_name }.map { |pair| pair[0]}
end
def save_pod_name_for_target(target)
folder = framework_folder_path_for_target_name(target.name)
return unless folder.exist?
flag_file_path = folder + "#{target.pod_name}.pod_name"
File.write(flag_file_path.to_s, "")
end
private
def pod_name_for_target_folder(target_folder_path)
name = Pathname.new(target_folder_path).children.find do |child|
child.to_s.end_with? ".pod_name"
end
name = name.basename(".pod_name").to_s unless name.nil?
name ||= Pathname.new(target_folder_path).basename.to_s # for compatibility with older version
end
# Array<[target_name, pod_name]>
def exsited_framework_name_pairs
return [] unless generate_framework_path.exist?
generate_framework_path.children().map do |framework_path|
if framework_path.directory? && (not framework_path.children.empty?)
[framework_path.basename.to_s, pod_name_for_target_folder(framework_path)]
else
nil
end
end.reject(&:nil?).uniq
end
end
end

View File

@ -1,3 +1,3 @@
module CocoapodsBinary
VERSION = "0.4.2"
VERSION = "0.4.4"
end

View File

@ -0,0 +1,27 @@
require_relative '../tool/tool'
module Pod
class Prebuild
class Context
class_attr_accessor :in_prebuild_stage
end
# Convenient method to return the condition proc object for patch.
# It indicates whether we are in prebuild stage.
# @return [Proc]
def self.prebuild_stage_condition
Proc.new do
Context.in_prebuild_stage
end
end
def self.integration_stage_condition
Proc.new do
!Context.in_prebuild_stage
end
end
end
end

View File

@ -1,5 +1,5 @@
require_relative '../tool/tool'
require_relative 'prebuild_sandbox'
require 'cocoapods-binary/tool/tool'
require_relative '../extensions/prebuild_sandbox'
module Pod
@ -18,34 +18,7 @@ module Pod
@@enable_prebuild_patch = value
end
# --- patch ---
old_method = instance_method(:pod)
define_method(:pod) do |name, *args|
if !@@enable_prebuild_patch
old_method.bind(self).(name, *args)
return
end
# patched content
should_prebuild = Pod::Podfile::DSL.prebuild_all
local = false
options = args.last
if options.is_a?(Hash) and options[Pod::Prebuild.keyword] != nil
should_prebuild = options[Pod::Prebuild.keyword]
local = (options[:path] != nil)
end
if should_prebuild and (not local)
if current_target_definition.platform == :watchos
# watchos isn't supported currently
Pod::UI.warn "Binary doesn't support watchos currently: #{name}. You can manually set `binary => false` for this pod to suppress this warning."
return
end
old_method.bind(self).(name, *args)
end
end
end
end
@ -59,7 +32,7 @@ module Pod
old_method = instance_method(:integrate_user_project)
define_method(:integrate_user_project) do
if @@force_disable_integration
return
next
end
old_method.bind(self).()
end
@ -74,7 +47,7 @@ module Pod
old_method = instance_method(:print_post_install_message)
define_method(:print_post_install_message) do
if @@disable_install_complete_message
return
next
end
old_method.bind(self).()
end
@ -92,9 +65,9 @@ module Pod
define_method(:lockfile_path) do
if @@force_disable_write_lockfile
# As config is a singleton, sandbox_root refer to the standard sandbox.
return PrebuildSandbox.from_standard_sanbox_path(sandbox_root).root + 'Manifest.lock.tmp'
next PrebuildSandbox.from_standard_sanbox_path(sandbox_root).root + 'Manifest.lock.tmp'
else
return old_method.bind(self).()
next old_method.bind(self).()
end
end
end

View File

@ -0,0 +1,80 @@
require_relative '../extensions/podfile_options'
module Pod
# Patch the podfile to let podfile only contain prebuild pods
# class Podfile
#
# class << self
#
# patch_method :from_ruby do |old_method, args|
# podfile = old_method.(*args)
# p podfile.root_target_definitions
# podfile
# end
#
# end
#
# end
# class Installer
#
# patch_method_before :install! do |*args|
# # manipulate the podfile, filter the binary pod
# if
# p podfile.root_target_definitions
# end
# end
class Prebuild
# @param [Podfile] podfile
def self.filter_podfile_content_for_prebuild_stage(podfile)
target_definitions = podfile.target_definition_list
all_explicit_pod_names = Set.new(target_definitions.map do |td|
td.prebuild_framework_pod_names(inherent_parent: false)
end.flatten)
target_definitions.each do |target_definition|
# pod dependency
values = target_definition.send(:get_hash_value, 'dependencies')
next if values.nil?
values = values.select do |v|
pod = nil
if v.kind_of?(Hash)
pod = v.keys.first
elsif v.kind_of?(String)
pod = v
else
raise "unexpect type: #{v.inspect}"
end
root_pod = Specification.root_name(pod)
all_explicit_pod_names.include?(root_pod)
end
# modify the data directly
target_definition.send(:set_hash_value, 'dependencies', values)
# podspec dependency
# podspec_dependencies
end
end
private def walk_the_tree(targets_definitions, &action)
return if targets_definitions.nil?
targets_definitions.each do |t|
action.call(t)
walk_the_tree(t.children, &action)
end
end
end
end

View File

@ -0,0 +1,78 @@
# ABOUT NAMES
#
# There are many kinds of name in cocoapods. Two main names are widely used in this plugin.
# - root_spec.name (spec.root_name, targe.pod_name):
# aka "pod_name"
# the name we use in podfile. the concept.
#
# - target.name:
# aka "target_name"
# the name of the final target in xcode project. the final real thing.
#
# One pod may have multiple targets in xcode project, due to one pod can be used in mutiple
# platform simultaneously. So one `root_spec.name` may have multiple coresponding `target.name`s.
# Therefore, map a spec to/from targets is a little complecated. It's one to many.
#
# Tool to transform Pod_name to target efficiently
module Pod
def self.fast_get_targets_for_pod_name(pod_name, targets, cache)
pod_name_to_targets_hash = nil
if cache.empty?
pod_name_to_targets_hash = targets.reduce({}) do |sum, target|
array = sum[target.pod_name] || []
array << target
sum[target.pod_name] = array
sum
end
cache << pod_name_to_targets_hash
else
pod_name_to_targets_hash = cache.first
end
pod_name_to_targets_hash[pod_name] || []
end
end
# Target:
# def pod_name
# root_spec.name
# end
# def name
# pod_name + #{scope_suffix}
# end
# def product_module_name
# root_spec.module_name
# end
# def framework_name
# "#{product_module_name}.framework"
# end
# def product_name
# if requires_frameworks?
# framework_name
# else
# static_library_name
# end
# end
# def product_basename
# if requires_frameworks?
# product_module_name
# else
# label
# end
# end
# def framework_name
# "#{product_module_name}.framework"
# end

View File

@ -1,110 +0,0 @@
module Pod
class Prebuild
def self.keyword
:binary
end
end
class Podfile
class TargetDefinition
## --- option for setting using prebuild framework ---
def parse_prebuild_framework(name, requirements)
should_prebuild = Pod::Podfile::DSL.prebuild_all
options = requirements.last
if options.is_a?(Hash) && options[Pod::Prebuild.keyword] != nil
should_prebuild = options.delete(Pod::Prebuild.keyword)
requirements.pop if options.empty?
end
pod_name = Specification.root_name(name)
set_prebuild_for_pod(pod_name, should_prebuild)
end
def set_prebuild_for_pod(pod_name, should_prebuild)
if should_prebuild == true
# watchos isn't supported currently
return if self.platform == :watchos
@prebuild_framework_names ||= []
@prebuild_framework_names.push pod_name
else
@should_not_prebuild_framework_names ||= []
@should_not_prebuild_framework_names.push pod_name
end
end
def prebuild_framework_names
names = @prebuild_framework_names || []
if parent != nil and parent.kind_of? TargetDefinition
names += parent.prebuild_framework_names
end
names
end
def should_not_prebuild_framework_names
names = @should_not_prebuild_framework_names || []
if parent != nil and parent.kind_of? TargetDefinition
names += parent.should_not_prebuild_framework_names
end
names
end
# ---- patch method ----
# We want modify `store_pod` method, but it's hard to insert a line in the
# implementation. So we patch a method called in `store_pod`.
old_method = instance_method(:parse_inhibit_warnings)
define_method(:parse_inhibit_warnings) do |name, requirements|
parse_prebuild_framework(name, requirements)
old_method.bind(self).(name, requirements)
end
end
end
end
module Pod
class Installer
def prebuild_pod_targets
all = []
aggregate_targets = self.aggregate_targets.select { |a| a.platform != :watchos }
aggregate_targets.each do |aggregate_target|
target_definition = aggregate_target.target_definition
targets = aggregate_target.pod_targets || []
# filter prebuild
prebuild_names = target_definition.prebuild_framework_names
if not Podfile::DSL.prebuild_all
targets = targets.select { |pod_target| prebuild_names.include?(pod_target.pod_name) }
end
dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
targets = (targets + dependency_targets).uniq
# filter should not prebuild
explict_should_not_names = target_definition.should_not_prebuild_framework_names
targets = targets.reject { |pod_target| explict_should_not_names.include?(pod_target.pod_name) }
all += targets
end
all = all.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
all.uniq
end
# the root names who needs prebuild, including dependency pods.
def prebuild_pod_names
@prebuild_pod_names ||= self.prebuild_pod_targets.map(&:pod_name)
end
end
end

View File

@ -1,49 +0,0 @@
module Pod
class PrebuildSandbox < Sandbox
# [String] standard_sandbox_path
def self.from_standard_sanbox_path(path)
prebuild_sandbox_path = Pathname.new(path).realpath + "_Prebuild"
self.new(prebuild_sandbox_path)
end
def self.from_standard_sandbox(sandbox)
self.from_standard_sanbox_path(sandbox.root)
end
def standard_sanbox_path
self.root.parent
end
def generate_framework_path
self.root + "GeneratedFrameworks"
end
def framework_folder_path_for_pod_name(name)
self.generate_framework_path + name
end
def exsited_framework_names
return [] unless generate_framework_path.exist?
generate_framework_path.children().map do |framework_name|
if framework_name.directory?
if not framework_name.children.empty?
File.basename(framework_name)
else
nil
end
else
nil
end
end.reject(&:nil?)
end
def framework_existed?(root_name)
return false unless generate_framework_path.exist?
generate_framework_path.children().any? do |child|
child.basename.to_s == root_name
end
end
end
end

View File

@ -0,0 +1,49 @@
module Pod
class Prebuild
# Check the targets, for the current limitation of the plugin
#
# @param [Array<PodTarget>] prebuilt_targets
def self.check_one_pod_should_have_only_one_target(prebuilt_targets)
targets_have_different_platforms = prebuilt_targets.select {|t| t.pod_name != t.name }
if targets_have_different_platforms.count > 0
names = targets_have_different_platforms.map(&:pod_name)
raw_names = targets_have_different_platforms.map(&:name)
message = "Oops, you came across a limitation of cocoapods-binary.
The plugin requires that one pod should have ONLY ONE target in the 'Pod.xcodeproj'. There are mainly 2 situations \
causing this problem:
1. One pod integrates in 2 or more different platforms' targets. e.g.
```
target 'iphoneApp' do
pod 'A', :binary => true
end
target 'watchApp' do
pod 'A'
end
```
2. Use different subspecs in multiple targets. e.g.
```
target 'iphoneApp' do
pod 'A/core'
pod 'A/network'
end
target 'iphoneAppTest' do
pod 'A/core'
end
```
Related pods: #{names}, target names: #{raw_names}
"
raise Informative, message
end
end
end
end

View File

@ -1,4 +1,5 @@
require 'fourflusher'
require 'xcpretty'
CONFIGURATION = "Release"
PLATFORMS = { 'iphonesimulator' => 'iOS',
@ -15,58 +16,92 @@ def build_for_iosish_platform(sandbox,
target,
device,
simulator,
bitcode_enabled)
bitcode_enabled,
custom_build_options = [], # Array<String>
custom_build_options_simulator = [] # Array<String>
)
deployment_target = target.platform.deployment_target.to_s
target_label = target.label
target_label = target.label # name with platform if it's used in multiple platforms
Pod::UI.puts "Prebuilding #{target_label}..."
other_options = []
if bitcode_enabled
other_options += ['BITCODE_GENERATION_MODE=bitcode']
end
xcodebuild(sandbox, target_label, device, deployment_target, other_options)
xcodebuild(sandbox, target_label, simulator, deployment_target, other_options + ['ARCHS=x86_64', 'ONLY_ACTIVE_ARCH=NO'])
other_options = []
# bitcode enabled
other_options += ['BITCODE_GENERATION_MODE=bitcode'] if bitcode_enabled
# make less arch to iphone simulator for faster build
custom_build_options_simulator += ['ARCHS=x86_64', 'ONLY_ACTIVE_ARCH=NO'] if simulator == 'iphonesimulator'
is_succeed, _ = xcodebuild(sandbox, target_label, device, deployment_target, other_options + custom_build_options)
exit 1 unless is_succeed
is_succeed, _ = xcodebuild(sandbox, target_label, simulator, deployment_target, other_options + custom_build_options_simulator)
exit 1 unless is_succeed
# paths
root_name = target.pod_name
target_name = target.name # equals target.label, like "AFNeworking-iOS" when AFNetworking is used in multiple platforms.
module_name = target.product_module_name
device_framwork_path = "#{build_dir}/#{CONFIGURATION}-#{device}/#{root_name}/#{module_name}.framework"
simulator_framwork_path = "#{build_dir}/#{CONFIGURATION}-#{simulator}/#{root_name}/#{module_name}.framework"
device_framework_path = "#{build_dir}/#{CONFIGURATION}-#{device}/#{target_name}/#{module_name}.framework"
simulator_framework_path = "#{build_dir}/#{CONFIGURATION}-#{simulator}/#{target_name}/#{module_name}.framework"
device_binary = device_framwork_path + "/#{module_name}"
simulator_binary = simulator_framwork_path + "/#{module_name}"
device_binary = device_framework_path + "/#{module_name}"
simulator_binary = simulator_framework_path + "/#{module_name}"
return unless File.file?(device_binary) && File.file?(simulator_binary)
# the device_lib path is the final output file path
# combine the bianries
tmp_lipoed_binary_path = "#{build_dir}/#{root_name}"
# combine the binaries
tmp_lipoed_binary_path = "#{build_dir}/#{target_name}"
lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_binary} #{simulator_binary}`
puts lipo_log unless File.exist?(tmp_lipoed_binary_path)
FileUtils.mv tmp_lipoed_binary_path, device_binary, :force => true
# collect the swiftmodule file for various archs.
device_swiftmodule_path = device_framwork_path + "/Modules/#{module_name}.swiftmodule"
simulator_swiftmodule_path = simulator_framwork_path + "/Modules/#{module_name}.swiftmodule"
device_swiftmodule_path = device_framework_path + "/Modules/#{module_name}.swiftmodule"
simulator_swiftmodule_path = simulator_framework_path + "/Modules/#{module_name}.swiftmodule"
if File.exist?(device_swiftmodule_path)
FileUtils.cp_r simulator_swiftmodule_path + "/.", device_swiftmodule_path
end
# combine the generated swift headers
# (In xcode 10.2, the generated swift headers vary for each archs)
# https://github.com/leavez/cocoapods-binary/issues/58
simulator_generated_swift_header_path = simulator_framework_path + "/Headers/#{module_name}-Swift.h"
device_generated_swift_header_path = device_framework_path + "/Headers/#{module_name}-Swift.h"
if File.exist? simulator_generated_swift_header_path
device_header = File.read(device_generated_swift_header_path)
simulator_header = File.read(simulator_generated_swift_header_path)
# https://github.com/Carthage/Carthage/issues/2718#issuecomment-473870461
combined_header_content = %Q{
#if TARGET_OS_SIMULATOR // merged by cocoapods-binary
#{simulator_header}
#else // merged by cocoapods-binary
#{device_header}
#endif // merged by cocoapods-binary
}
File.write(device_generated_swift_header_path, combined_header_content.strip)
end
# handle the dSYM files
device_dsym = "#{device_framwork_path}.dSYM"
device_dsym = "#{device_framework_path}.dSYM"
if File.exist? device_dsym
# lipo the simulator dsym
tmp_lipoed_binary_path = "#{output_path}/#{module_name}.draft"
lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_dsym}/Contents/Resources/DWARF/#{module_name} #{simulator_framwork_path}.dSYM/Contents/Resources/DWARF/#{module_name}`
puts lipo_log unless File.exist?(tmp_lipoed_binary_path)
FileUtils.mv tmp_lipoed_binary_path, "#{device_framwork_path}.dSYM/Contents/Resources/DWARF/#{module_name}", :force => true
simulator_dsym = "#{simulator_framework_path}.dSYM"
if File.exist? simulator_dsym
tmp_lipoed_binary_path = "#{output_path}/#{module_name}.draft"
lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_dsym}/Contents/Resources/DWARF/#{module_name} #{simulator_dsym}/Contents/Resources/DWARF/#{module_name}`
puts lipo_log unless File.exist?(tmp_lipoed_binary_path)
FileUtils.mv tmp_lipoed_binary_path, "#{device_framework_path}.dSYM/Contents/Resources/DWARF/#{module_name}", :force => true
end
# move
FileUtils.mv device_dsym, output_path, :force => true
end
# output
output_path.mkpath unless output_path.exist?
FileUtils.mv device_framwork_path, output_path, :force => true
FileUtils.mv device_framework_path, output_path, :force => true
end
@ -75,7 +110,27 @@ def xcodebuild(sandbox, target, sdk='macosx', deployment_target=nil, other_optio
platform = PLATFORMS[sdk]
args += Fourflusher::SimControl.new.destination(:oldest, platform, deployment_target) unless platform.nil?
args += other_options
Pod::Executable.execute_command 'xcodebuild', args, true
log = `xcodebuild #{args.join(" ")} 2>&1`
exit_code = $?.exitstatus # Process::Status
is_succeed = (exit_code == 0)
if !is_succeed
begin
if log.include?('** BUILD FAILED **')
# use xcpretty to print build log
# 64 represent command invalid. http://www.manpagez.com/man/3/sysexits/
printer = XCPretty::Printer.new({:formatter => XCPretty::Simple, :colorize => 'auto'})
log.each_line do |line|
printer.pretty_print(line)
end
else
raise "shouldn't be handle by xcpretty"
end
rescue
puts log.red
end
end
[is_succeed, log]
end
@ -94,9 +149,9 @@ module Pod
# [Pathname] output_path
# output path for generated frameworks
#
def self.build(sandbox_root_path, target, output_path, bitcode_enabled = false)
def self.build(sandbox_root_path, target, output_path, bitcode_enabled = false, custom_build_options=[], custom_build_options_simulator=[])
return unless not target == nil
return if target.nil?
sandbox_root = Pathname(sandbox_root_path)
sandbox = Pod::Sandbox.new(sandbox_root)
@ -104,10 +159,10 @@ module Pod
# -- build the framework
case target.platform.name
when :ios then build_for_iosish_platform(sandbox, build_dir, output_path, target, 'iphoneos', 'iphonesimulator', bitcode_enabled)
when :osx then xcodebuild(sandbox, target.label)
when :ios then build_for_iosish_platform(sandbox, build_dir, output_path, target, 'iphoneos', 'iphonesimulator', bitcode_enabled, custom_build_options, custom_build_options_simulator)
when :osx then xcodebuild(sandbox, target.label, 'macosx', nil, custom_build_options)
# when :tvos then build_for_iosish_platform(sandbox, build_dir, target, 'appletvos', 'appletvsimulator')
# when :watchos then build_for_iosish_platform(sandbox, build_dir, target, 'watchos', 'watchsimulator')
when :watchos then build_for_iosish_platform(sandbox, build_dir, output_path, target, 'watchos', 'watchsimulator', true, custom_build_options, custom_build_options_simulator)
else raise "Unsupported platform for '#{target.name}': '#{target.platform.name}'" end
raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?

View File

@ -0,0 +1,19 @@
class AssertError < StandardError
end
def assert(condition, message="")
raise AssertError, message unless condition
end
def assert_type(variable, type_class)
assert(variable.kind_of?(type_class), "Type is incorrect: #{variable.class} is not #{type_class}")
end
def assert_type_array_of(variable, type_class)
assert type_class != nil,'Input type is nil'
assert_type variable, Array
if variable.first
assert_type variable.first, type_class
end
end

View File

@ -0,0 +1,13 @@
# attr_accessor for class variable.
# usage:
#
# ```
# class Pod
# class_attr_accessor :is_prebuild_stage
# end
# ```
#
def class_attr_accessor(symbol)
self.class.send(:attr_accessor, symbol)
end

View File

@ -0,0 +1,9 @@
module UI
# print log only when verbose
def verbose_log(message)
return unless config.verbose?
UI.puts message
end
end

View File

@ -0,0 +1,49 @@
# Patch a method
# @param [Symbol] method_name
# @param [block] content, args: 1 old_method, 2 the array of original args
# ```
# patch_method :AAA do |old_method, args|
# old_method.(*args) # execute the original method
# end
# ```
def patch_method(method_name, &content)
return if content.nil?
old = instance_method(method_name)
raise "Found no method named: #{method_name}" if old.nil?
define_method(method_name) do |*args|
instance_exec old.bind(self), args, &content
end
end
# It won't change the return value of the original method
# @param [Symbol] method_name
# @param [block] content, args: the original args
# ```
# patch_method_after :AAA do |*args|
# # execute the original method
# # the added actions
# puts "after the original action"
# # return the original result
# end
# ```
def patch_method_after(method_name, &content)
return if content.nil?
patch_method(method_name) do |old_method, args|
old_result = old_method.(*args)
instance_exec *args, &content
next old_result
end
end
# @param [Symbol] method_name
# @param [block] content, args: the original args
def patch_method_before(method_name, &content)
return if content.nil?
patch_method(method_name) do |old_method, args|
instance_exec *args, &content
next old_method.(*args)
end
end

View File

@ -0,0 +1,49 @@
require_relative 'patch_method'
require_relative 'assert'
# Only execute the patched content when condition returns true,
# otherwise execute the original method.
#
# @param [Proc return bool] only_when: the condition
# @see patch_method
def modify_method(method_name, only_when:, &content)
condition = only_when
assert_type condition, Proc
patch_method(method_name) do |old_method, args|
if condition.call
instance_exec old_method, args, &content
else
old_method.(*args)
end
end
end
# @see patch_method_after
def do_after_method(method_name, only_when:, &content)
condition = only_when
assert_type condition, Proc
patch_method(method_name) do |old_method, args|
if condition.call
old_result = old_method.(*args)
instance_exec *args, &content
next old_result
else
old_method.(*args)
end
end
end
# @see patch_method_before
def do_before_method(method_name, only_when:, &content)
condition = only_when
assert_type condition, Proc
patch_method(method_name) do |old_method, args|
if condition.call
instance_exec *args, &content
old_method.(*args)
else
old_method.(*args)
end
end
end

View File

@ -1,12 +1,5 @@
# attr_accessor for class variable.
# usage:
#
# ```
# class Pod
# class_attr_accessor :is_prebuild_stage
# end
# ```
#
def class_attr_accessor(symbol)
self.class.send(:attr_accessor, symbol)
end
require_relative 'assert'
require_relative 'class_attr_accessor'
require_relative 'patch_method'
require_relative 'patch_method_when'
require_relative 'log'

View File

@ -0,0 +1,84 @@
# require 'spec_helper'
# require 'cocoapods-binary/Prebuild'
#
#
# module Pod
#
#
# describe 'Prebuild' do
# describe 'Install' do
# describe 'Retry Mechanism' do
#
# before(:each) do
# SpecHelper.prebuild_installer_stubs(self)
# end
#
# context 'when explicitly set requirements for dependencies and make it non-binary' do
# before(:each) do
# SpecHelper.stub_pod_dependencies(self, {
# RxCocoa: [['RxSwift', '>=4.4.0']],
# RxSwift: ['RxAtomic', '4.4.0'],
# })
# @installer, @sandbox, @podfile = Pod.build_installer do
# target 'A' do
# pod "RxCocoa", '4.4.0', :binary => true
# pod "RxSwift", '4.5.0', :binary => false
# pod "SnapKit"
# end
# end
# end
#
# it "should throw a error when analyze dependency" do
# class SpecError < StandardError; end
# expect(@installer).to receive(:resolve_dependencies).and_wrap_original { |m, *args|
# begin
# m.call(*args)
# rescue Installer::PrebuildMissingRequirementError => e
# expect(e.missing_pod_names).to match_array(['RxSwift'])
# raise SpecError, '1'
# end
# }
# expect{
# @installer.install!
# }.to raise_error(SpecError)
# end
#
# it "should retry (regenerate the installer and install)" do
# expect(@installer).to receive(:regenerate_installer).exactly(:once).and_wrap_original { |m , *args|
# new_installer = m.call(*args)
# expect(new_installer).to receive(:install!).and_call_original
# new_installer
# }
# @installer.install!
# end
#
# end
#
# context 'when have nest requirements' do
# before(:each) do
# SpecHelper.stub_pod_dependencies(self, {
# RxCocoa: [['RxSwift', '>=4.4.0']],
# RxSwift: ['RxAtomic', '4.4.0'],
# RxAtomic: ['SnapKit', '>1.0']
# })
# @installer, @sandbox, @podfile = Pod.build_installer do
# target 'A' do
# pod "RxCocoa", '4.4.0', :binary => true
# pod "RxSwift", '4.5.0', :binary => false
# pod "SnapKit", '4.0.1', :binary => false
# end
# end
# end
#
#
# it "should retry twice" do
# # expect_any_instance_of(Installer).to receive(:regenerate_installer).exactly(2).and_call_original
# # @installer.install!
# end
#
# end
#
# end
# end
# end
# end

301
spec/prebuild_spec.rb Normal file
View File

@ -0,0 +1,301 @@
require 'spec_helper'
require 'cocoapods-binary/Prebuild'
module Pod
describe 'Prebuild' do
describe 'Install' do
before(:each) do
SpecHelper.prebuild_installer_stubs(self)
# data_flow = Prebuild::DataFlow.clone.instance
# allow_any_instance_of(Prebuild::DataFlow).to receive(:instance) { data_flow }
end
describe 'Pod binarify strategy' do
context 'when set some pod to binary' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, { })
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "AFNetworking", :binary => true
pod "SnapKit"
end
end
@installer.install!
end
it "should have right pod target" do
@installer.pod_targets.map(&:name).should match_array(['AFNetworking'])
end
it "should have right binary pod" do
@installer.prebuild_pod_targets.map(&:name).should match_array(['AFNetworking'])
end
end
context 'when explicitly turn off a pod' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, {
RxCocoa: ['RxSwift', '4.4.0'],
RxSwift: ['RxAtomic', '4.4.0'],
})
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "RxSwift", '4.4.0', :binary => false
pod "RxCocoa", '4.4.0', :binary => true
pod "SnapKit"
end
end
@installer.install!
end
it "should exclude the off in prebuild target" do
@installer.prebuild_pod_targets.map(&:name).should match_array(['RxAtomic', 'RxCocoa'])
end
it "should also have all dependencies in Pod project (for building)" do
@installer.pod_targets.map(&:name).should match_array(['RxAtomic', 'RxCocoa', 'RxSwift'])
end
end
context 'when binary pod have dependencies' do
context 'when implicit set dependencies' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, {
RxCocoa: ['RxSwift', '4.4.0'],
RxSwift: ['RxAtomic', '4.4.0'],
})
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "RxCocoa", '4.4.0', :binary => true
pod "SnapKit"
end
end
@installer.install!
end
it "should have include all dependencies" do
[@installer.prebuild_pod_targets, @installer.pod_targets].each do |targets|
targets.map(&:name).should match_array(['RxAtomic', 'RxCocoa', 'RxSwift'])
end
end
end
context 'when explicitly set version for dependencies and make it non-binary' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, {
RxCocoa: [['RxSwift', '>=4.4.0']],
RxSwift: ['RxAtomic', '4.4.0'],
})
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "RxCocoa", '4.4.0', :binary => true
pod "RxSwift", '4.5.0', :binary => false
pod "SnapKit"
end
end
@installer.install!
end
it "should exclude the explicit off" do
@installer.prebuild_pod_targets.map(&:name).should match_array(['RxAtomic', 'RxCocoa'])
end
# doc_anchor
it "should have the right version for the explicit off" do
rxswift = @installer.pod_targets.find{ |t|t.pod_name == 'RxSwift'}
rxswift.should_not be_nil
spec = @installer.analysis_result.specifications.find{ |s|s.name == 'RxSwift'}
spec.version.to_s.should == '4.5.0'
end
it "should have all the dependencies to build in Pod project" do
@installer.pod_targets.map(&:name).should match_array(['RxAtomic', 'RxCocoa', 'RxSwift'])
end
end
context 'when explicitly set config for dependencies and make it non-binary(subspec)' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, {
'SnapKit' => ['AFNetworking/Reachability', '>=3.1.0'],
'AFNetworking/Reachability' => [],
})
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "SnapKit", :binary => true
pod "AFNetworking/Reachability", '3.2.0', :binary => false
end
end
@installer.install!
end
it "should exclude the explicit off" do
@installer.prebuild_pod_targets.map(&:name).should match_array(['SnapKit'])
end
# doc_anchor
it "should have the right version for the explicit off" do
target = @installer.pod_targets.find{ |t|t.pod_name == 'AFNetworking'}
target.should_not be_nil
spec = @installer.analysis_result.specifications.find{ |s|s.name == 'AFNetworking/Reachability'}
spec.version.to_s.should == '3.2.0'
end
it "should have all the dependencies to build in Pod project" do
@installer.pod_targets.map(&:name).should match_array(['SnapKit', 'AFNetworking'])
end
end
end
context "When use multiple platforms" do
before(:each) do
SpecHelper.stub_pod_dependencies(self, { })
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
platform :ios
pod "AFNetworking", :binary => true
end
target 'B' do
platform :watchos
pod "AFNetworking", :binary => false
end
end
@installer.install!
end
it "should have targets named with (pod_name + platform) " do
@installer.prebuild_pod_targets.map(&:name).should match_array(["AFNetworking-iOS", "AFNetworking-watchOS"])
end
it "for one pod, targets on different platforms should all be binary if one platform is binary" do
@installer.prebuild_pod_targets.map(&:pod_name).should match_array(["AFNetworking", "AFNetworking"])
end
end
context "When use subspecs" do
context 'when subspecs have different binary state' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, { })
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "AFNetworking/Reachability", :binary => true
pod "AFNetworking/Security", :binary => false
pod "SnapKit"
end
end
@installer.install!
end
it "should have target named with pod name " do
@installer.pod_targets.map(&:name).should match_array(['AFNetworking'])
end
it "should have all used subspec content (even a subspec is set to off explicitly)" do
target = @installer.pod_targets.first
target.specs.map(&:name).should match_array ['AFNetworking/Reachability', 'AFNetworking/Security']
end
end
context 'when use subspec in different targets' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, { })
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "AFNetworking/Security", :binary => true
end
target 'B' do
pod "AFNetworking/Security", :binary => false # or true
end
end
@installer.install!
end
it "the binary target's name should equal to root pod name " do
@installer.prebuild_pod_targets.map(&:name).should match_array(['AFNetworking'])
end
it "should have just enough subspec content" do
target = @installer.prebuild_pod_targets.first
target.specs.map(&:name).should match_array ['AFNetworking/Security']
end
end
context 'when use different subspecs in different targets' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, { })
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "AFNetworking/Reachability", :binary => true
end
target 'B' do
pod "AFNetworking/Security", :binary => false
end
end
end
#TODO
xit "should not be supported" do
# ["AFNetworking-Reachability", "AFNetworking-Security"]
expect {
@installer.install!
}.to raise_error
end
end
context 'when subspecs have dependency' do
before(:each) do
SpecHelper.stub_pod_dependencies(self, {
'AFNetworking/Security'.to_sym => ['Masonry', '1.1.0']
})
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "AFNetworking/Security", :binary => true
end
end
@installer.install!
end
it "should have just enough content" do
target = @installer.prebuild_pod_targets.first
target.specs.map(&:name).should match_array ['AFNetworking/Security']
@installer.prebuild_pod_targets.map(&:name).should match_array(['AFNetworking', 'Masonry'])
end
end
end
context "when have local pod" do
before(:each) do
SpecHelper.stub_pod_dependencies(self, { })
allow_any_instance_of(Specification).to receive(:local?) { |s|
next true if s.name == 'AFNetworking' or s.name == 'SnapKit'
false
}
@installer, @sandbox, @podfile = Pod.build_installer do
target 'A' do
pod "AFNetworking/Security", :binary => true # mock it to local
pod "SnapKit", :binary => true # mock it to local
pod "Literal", :binary => true
end
end
@installer.install!
end
it "local pod should be exclude" do
@installer.prebuild_pod_targets.map(&:name).should match_array(['Literal'])
end
it "local pod should still in project" do
@installer.pod_targets.map(&:name).should match_array(['AFNetworking', 'Literal', 'SnapKit'])
end
end
end
end
end
end

View File

@ -1,19 +1,16 @@
require 'pathname'
ROOT = Pathname.new(File.expand_path('../../', __FILE__))
$:.unshift((ROOT + 'lib').to_s)
$:.unshift((ROOT + 'spec').to_s)
require 'bundler/setup'
require 'bacon'
require 'mocha-on-bacon'
require 'pretty_bacon'
require 'pathname'
require 'cocoapods'
Mocha::Configuration.prevent(:stubbing_non_existent_method)
require 'cocoapods_plugin'
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = [:should, :expect]
end
config.mock_with :rspec do |mocks|
mocks.syntax = [:expect, :should]
end
end
#-----------------------------------------------------------------------------#
module Pod
@ -48,3 +45,82 @@ module Pod
end
#-----------------------------------------------------------------------------#
module Pod
def self.build_installer(&podfile_text)
# Config.instance.silent = true
sandbox = Sandbox.new(Dir.tmpdir + "/binary_spec_#{Time.new.to_i}")
block = Proc.new do
platform :ios, '12.0'
instance_eval &podfile_text
end
podfile = Podfile.new &block
podfile.instance_eval do
@initial_block = block
end
installer = Installer.new(sandbox, podfile)
installer.installation_options.integrate_targets = false
[installer, sandbox, podfile]
end
module SpecHelper
# mock the methods for installer
def self.prebuild_installer_stubs(context)
context.instance_eval do
allow_any_instance_of(Installer).to receive(:prebuild_frameworks!) { }
[:download_dependencies, :validate_targets, :generate_pods_project, :perform_post_install_actions].each do |method|
allow_any_instance_of(Installer).to receive(method) { }
end
Prebuild::Context.stub(:in_prebuild_stage).and_return(true)
allow_any_instance_of(Installer).to receive(:regenerate_original_podfile) { |s|
block = s.podfile.instance_variable_get(:@initial_block) # set in the #build_installer method
assert block != nil
podfile = Podfile.new(&block)
podfile.instance_variable_set(:@initial_block, block)
podfile
}
end
end
# mock the dependency of pods, as the dependency may changed along pod version
# @param [Hash<Symbol, Array<Arrary<String>>>] modification
def self.stub_pod_dependencies(context, modification)
raise if modification.nil?
if !@specification_hooked
Specification.class_eval do
p "chenage!!!!"
alias_method :original_dependencies, :dependencies
end
@specification_hooked = true
end
context.instance_eval do
allow_any_instance_of(Specification).to receive(:dependencies) { |s|
deps = modification[s.name.to_sym] || modification[s.name.to_s]
if deps
if deps == []
next []
end
if deps.first.kind_of? String
deps = [deps]
end
next deps.map{ |name_and_version| Dependency.new(name_and_version[0].to_s, name_and_version[1]) }
end
if modification[:keep_untouched]
next s.original_dependencies
else
[]
end
}
end
end
end
end

View File

@ -0,0 +1,287 @@
require 'rspec'
require 'cocoapods-binary/tool/patch_method'
describe 'Patch method' do
it 'should patch the content' do
module SpecPatchMethod
class A
def m
"1"
end
patch_method('m') do |old_method, args|
"2"
end
end
ins = A.new
ins.m().should == '2'
end
end
it 'should keep the args' do
module SpecPatchMethod
class B
def m(a, b)
"1#{a}#{b}"
end
patch_method('m') do |old_method, args|
"2#{args[0]}#{args[1]}"
end
end
ins = B.new
ins.m(1,2).should == '212'
end
end
it "should have right scope" do
module SpecPatchMethod
class C
def m
end
def who_am_i
self.class.name
end
patch_method('m') do |old_method, args|
who_am_i
end
end
C.new.m.should == 'SpecPatchMethod::C'
end
end
it "the original method is can be accessed" do
module SpecPatchMethod
class D
def m(a)
"1#{a}"
end
patch_method('m') do |old_method, args|
old_method.(*args)
end
end
D.new.m(2).should == '12'
end
end
it "can call multiple times" do
module SpecPatchMethod
class E
def m(a)
"0#{a}"
end
patch_method('m') do |old_method, args|
old_method.(*args) + "2"
end
patch_method('m') do |old_method, args|
old_method.(*args) + "3"
end
end
E.new.m(1).should == '0123'
end
end
it "can keep original default value" do
module SpecPatchMethod
class F
def m(a='D')
"0#{a}"
end
patch_method('m') do |old_method, args|
old_method.(*args) + "2"
end
patch_method('m') do |old_method, args|
old_method.(*args) + "3"
end
end
F.new.m().should == '0D23'
F.new.m(1).should == '0123'
end
end
end
describe 'Patch method before' do
it 'should patch the content' do
module SpecPatchMethodBefore
class A
attr_accessor :output
def m
output << 1
end
patch_method_before('m') do |*args|
self.output = [2]
end
end
a = A.new
a.m().should == [2, 1]
end
end
it 'should keep the args' do
module SpecPatchMethodBefore
class B
attr_accessor :output
def m(a,b)
self.output ||= []
output << a
output << b
end
patch_method_before('m') do |*args|
self.output ||= []
self.output += args
end
end
a = B.new
a.m(1,2)
a.output.should == [1,2,1,2]
end
end
it "should have right scope" do
module SpecPatchMethodBefore
class C
attr_accessor :output
def m
end
def do_it
self.output = 1
end
patch_method_before('m') do
do_it
end
end
a = C.new
a.m
a.output.should == 1
end
end
it "won't affect the original result" do
module SpecPatchMethodBefore
class D
def m(a)
"1#{a}"
end
patch_method_before('m') do |*args|
nil
end
end
D.new.m(2).should == '12'
end
end
end
describe 'Patch method after' do
it 'should patch the content' do
module SpecPatchMethodAfter
class A
attr_accessor :output
def m
self.output = [2]
end
patch_method_after('m') do |*args|
output << 1
end
end
a = A.new
a.m().should == [2, 1]
end
end
it 'should keep the args' do
module SpecPatchMethodAfter
class B
attr_accessor :output
def m(a,b)
self.output ||= []
output << a
output << b
end
patch_method_after('m') do |*args|
self.output ||= []
self.output += args
end
end
a = B.new
a.m(1,2)
a.output.should == [1,2,1,2]
end
end
it "should have right scope" do
module SpecPatchMethodAfter
class C
attr_accessor :output
def m
end
def do_it
self.output = 1
end
patch_method_after('m') do
do_it
end
end
a = C.new
a.m
a.output.should == 1
end
end
it "won't affect the original result" do
module SpecPatchMethodAfter
class D
def m(a)
"1#{a}"
end
patch_method_after('m') do |*args|
nil
end
end
D.new.m(2).should == '12'
end
end
end

View File

@ -0,0 +1,105 @@
require 'rspec'
require 'cocoapods-binary/tool/patch_method_when'
describe 'Patch method when' do
it 'should patch the content' do
module SpecPatchMethodWhen
class A
def m
"1"
end
modify_method('m', only_when: Proc.new{ true }) do |old_method, args|
"2"
end
end
ins = A.new
ins.m().should == '2'
end
end
it "the condition switch should be valid " do
module SpecPatchMethodWhen
class Switch
class << self
attr_accessor :on
end
end
class G
def m
"1"
end
modify_method('m', only_when: Proc.new{ Switch.on }) do |old_method, args|
"2"
end
end
ins = G.new
Switch.on = true
ins.m().should == '2'
Switch.on = false
ins.m().should == '1'
end
end
it 'should keep the args' do
module SpecPatchMethodWhen
class B
def m(a, b)
"1#{a}#{b}"
end
modify_method('m', only_when: Proc.new{ true }) do |old_method, args|
"2#{args[0]}#{args[1]}"
end
end
ins = B.new
ins.m(1,2).should == '212'
end
end
it "should have right scope" do
module SpecPatchMethodWhen
class C
def m
end
def who_am_i
self.class.name
end
modify_method('m', only_when: Proc.new{ true }) do |old_method, args|
who_am_i
end
end
C.new.m.should == 'SpecPatchMethodWhen::C'
end
end
it "the original method is can be accessed" do
module SpecPatchMethodWhen
class D
def m(a)
"1#{a}"
end
modify_method('m', only_when: Proc.new{ true }) do |old_method, args|
old_method.(*args)
end
end
D.new.m(2).should == '12'
end
end
end

3
spec/tool/tool_spec.rb Normal file
View File

@ -0,0 +1,3 @@
require 'rspec'

View File

@ -10,9 +10,59 @@
3E1E218020A0B66900EFA102 /* import.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E1E217F20A0B66900EFA102 /* import.swift */; };
3E83E326207BC00E0057855A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E83E325207BC00E0057855A /* AppDelegate.swift */; };
3E83E328207BC00E0057855A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E83E327207BC00E0057855A /* ViewController.swift */; };
3EEAFD8720F1056D009A9D22 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3EEAFD8520F1056D009A9D22 /* Interface.storyboard */; };
3EEAFD8920F1056D009A9D22 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3EEAFD8820F1056D009A9D22 /* Assets.xcassets */; };
3EEAFD9020F1056E009A9D22 /* BinaryWatch Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3EEAFD8F20F1056E009A9D22 /* BinaryWatch Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
3EEAFD9520F1056E009A9D22 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EEAFD9420F1056E009A9D22 /* InterfaceController.swift */; };
3EEAFD9720F1056E009A9D22 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EEAFD9620F1056E009A9D22 /* ExtensionDelegate.swift */; };
3EEAFD9920F1056E009A9D22 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3EEAFD9820F1056E009A9D22 /* Assets.xcassets */; };
3EEAFD9D20F1056E009A9D22 /* BinaryWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 3EEAFD8320F1056D009A9D22 /* BinaryWatch.app */; };
3EEAFDA720F10610009A9D22 /* import.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EEAFDA620F10610009A9D22 /* import.swift */; };
AEBC61E3160A9AC38C3A210D /* Pods_Binary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5687B1A81F152DBEF5CD4432 /* Pods_Binary.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
3EEAFD9120F1056E009A9D22 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 3E83E31A207BC00E0057855A /* Project object */;
proxyType = 1;
remoteGlobalIDString = 3EEAFD8E20F1056E009A9D22;
remoteInfo = "BinaryWatch Extension";
};
3EEAFD9B20F1056E009A9D22 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 3E83E31A207BC00E0057855A /* Project object */;
proxyType = 1;
remoteGlobalIDString = 3EEAFD8220F1056D009A9D22;
remoteInfo = BinaryWatch;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
3EEAFDA320F1056E009A9D22 /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
3EEAFD9020F1056E009A9D22 /* BinaryWatch Extension.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
3EEAFDA520F1056E009A9D22 /* Embed Watch Content */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
dstSubfolderSpec = 16;
files = (
3EEAFD9D20F1056E009A9D22 /* BinaryWatch.app in Embed Watch Content */,
);
name = "Embed Watch Content";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1856F5E2BE44EDB1E470521A /* Pods-Binary.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Binary.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Binary/Pods-Binary.debug.xcconfig"; sourceTree = "<group>"; };
3E1E217F20A0B66900EFA102 /* import.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = import.swift; sourceTree = "<group>"; };
@ -20,6 +70,16 @@
3E83E325207BC00E0057855A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
3E83E327207BC00E0057855A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
3E83E331207BC0120057855A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3EEAFD8320F1056D009A9D22 /* BinaryWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BinaryWatch.app; sourceTree = BUILT_PRODUCTS_DIR; };
3EEAFD8620F1056D009A9D22 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = "<group>"; };
3EEAFD8820F1056D009A9D22 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
3EEAFD8A20F1056E009A9D22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3EEAFD8F20F1056E009A9D22 /* BinaryWatch Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "BinaryWatch Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
3EEAFD9420F1056E009A9D22 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = "<group>"; };
3EEAFD9620F1056E009A9D22 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = "<group>"; };
3EEAFD9820F1056E009A9D22 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
3EEAFD9A20F1056E009A9D22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3EEAFDA620F10610009A9D22 /* import.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = import.swift; sourceTree = "<group>"; };
5687B1A81F152DBEF5CD4432 /* Pods_Binary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Binary.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7EB848DBE64BD495BCC04ECC /* Pods-Binary.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Binary.release.xcconfig"; path = "Pods/Target Support Files/Pods-Binary/Pods-Binary.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -33,6 +93,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
3EEAFD8C20F1056E009A9D22 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@ -40,6 +107,8 @@
isa = PBXGroup;
children = (
3E83E324207BC00E0057855A /* Binary */,
3EEAFD8420F1056D009A9D22 /* BinaryWatch */,
3EEAFD9320F1056E009A9D22 /* BinaryWatch Extension */,
3E83E323207BC00E0057855A /* Products */,
E8117D681BF19C1B3D847824 /* Pods */,
8E13F0A6AED19C681C2CD7D5 /* Frameworks */,
@ -50,6 +119,8 @@
isa = PBXGroup;
children = (
3E83E322207BC00E0057855A /* Binary.app */,
3EEAFD8320F1056D009A9D22 /* BinaryWatch.app */,
3EEAFD8F20F1056E009A9D22 /* BinaryWatch Extension.appex */,
);
name = Products;
sourceTree = "<group>";
@ -65,6 +136,28 @@
path = Binary;
sourceTree = "<group>";
};
3EEAFD8420F1056D009A9D22 /* BinaryWatch */ = {
isa = PBXGroup;
children = (
3EEAFD8520F1056D009A9D22 /* Interface.storyboard */,
3EEAFD8820F1056D009A9D22 /* Assets.xcassets */,
3EEAFD8A20F1056E009A9D22 /* Info.plist */,
);
path = BinaryWatch;
sourceTree = "<group>";
};
3EEAFD9320F1056E009A9D22 /* BinaryWatch Extension */ = {
isa = PBXGroup;
children = (
3EEAFD9420F1056E009A9D22 /* InterfaceController.swift */,
3EEAFD9620F1056E009A9D22 /* ExtensionDelegate.swift */,
3EEAFDA620F10610009A9D22 /* import.swift */,
3EEAFD9820F1056E009A9D22 /* Assets.xcassets */,
3EEAFD9A20F1056E009A9D22 /* Info.plist */,
);
path = "BinaryWatch Extension";
sourceTree = "<group>";
};
8E13F0A6AED19C681C2CD7D5 /* Frameworks */ = {
isa = PBXGroup;
children = (
@ -94,29 +187,71 @@
3E83E31F207BC00E0057855A /* Frameworks */,
3E83E320207BC00E0057855A /* Resources */,
9937F6A880D56826534273F0 /* [CP] Embed Pods Frameworks */,
3EEAFDA520F1056E009A9D22 /* Embed Watch Content */,
);
buildRules = (
);
dependencies = (
3EEAFD9C20F1056E009A9D22 /* PBXTargetDependency */,
);
name = Binary;
productName = Binary;
productReference = 3E83E322207BC00E0057855A /* Binary.app */;
productType = "com.apple.product-type.application";
};
3EEAFD8220F1056D009A9D22 /* BinaryWatch */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3EEAFDA420F1056E009A9D22 /* Build configuration list for PBXNativeTarget "BinaryWatch" */;
buildPhases = (
3EEAFD8120F1056D009A9D22 /* Resources */,
3EEAFDA320F1056E009A9D22 /* Embed App Extensions */,
);
buildRules = (
);
dependencies = (
3EEAFD9220F1056E009A9D22 /* PBXTargetDependency */,
);
name = BinaryWatch;
productName = BinaryWatch;
productReference = 3EEAFD8320F1056D009A9D22 /* BinaryWatch.app */;
productType = "com.apple.product-type.application.watchapp2";
};
3EEAFD8E20F1056E009A9D22 /* BinaryWatch Extension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3EEAFDA220F1056E009A9D22 /* Build configuration list for PBXNativeTarget "BinaryWatch Extension" */;
buildPhases = (
3EEAFD8B20F1056E009A9D22 /* Sources */,
3EEAFD8C20F1056E009A9D22 /* Frameworks */,
3EEAFD8D20F1056E009A9D22 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "BinaryWatch Extension";
productName = "BinaryWatch Extension";
productReference = 3EEAFD8F20F1056E009A9D22 /* BinaryWatch Extension.appex */;
productType = "com.apple.product-type.watchkit2-extension";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
3E83E31A207BC00E0057855A /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0930;
LastSwiftUpdateCheck = 1000;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = me.leavez;
TargetAttributes = {
3E83E321207BC00E0057855A = {
CreatedOnToolsVersion = 9.3;
};
3EEAFD8220F1056D009A9D22 = {
CreatedOnToolsVersion = 10.0;
};
3EEAFD8E20F1056E009A9D22 = {
CreatedOnToolsVersion = 10.0;
};
};
};
buildConfigurationList = 3E83E31D207BC00E0057855A /* Build configuration list for PBXProject "Binary" */;
@ -133,6 +268,8 @@
projectRoot = "";
targets = (
3E83E321207BC00E0057855A /* Binary */,
3EEAFD8220F1056D009A9D22 /* BinaryWatch */,
3EEAFD8E20F1056E009A9D22 /* BinaryWatch Extension */,
);
};
/* End PBXProject section */
@ -145,6 +282,23 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
3EEAFD8120F1056D009A9D22 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3EEAFD8920F1056D009A9D22 /* Assets.xcassets in Resources */,
3EEAFD8720F1056D009A9D22 /* Interface.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
3EEAFD8D20F1056E009A9D22 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3EEAFD9920F1056E009A9D22 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@ -199,8 +353,42 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
3EEAFD8B20F1056E009A9D22 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3EEAFD9720F1056E009A9D22 /* ExtensionDelegate.swift in Sources */,
3EEAFDA720F10610009A9D22 /* import.swift in Sources */,
3EEAFD9520F1056E009A9D22 /* InterfaceController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
3EEAFD9220F1056E009A9D22 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 3EEAFD8E20F1056E009A9D22 /* BinaryWatch Extension */;
targetProxy = 3EEAFD9120F1056E009A9D22 /* PBXContainerItemProxy */;
};
3EEAFD9C20F1056E009A9D22 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 3EEAFD8220F1056D009A9D22 /* BinaryWatch */;
targetProxy = 3EEAFD9B20F1056E009A9D22 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
3EEAFD8520F1056D009A9D22 /* Interface.storyboard */ = {
isa = PBXVariantGroup;
children = (
3EEAFD8620F1056D009A9D22 /* Base */,
);
name = Interface.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
3E83E332207BC0120057855A /* Debug */ = {
isa = XCBuildConfiguration;
@ -322,7 +510,10 @@
buildSettings = {
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = Binary/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.Binary;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
@ -336,7 +527,10 @@
buildSettings = {
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = Binary/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.Binary;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
@ -344,6 +538,86 @@
};
name = Release;
};
3EEAFD9E20F1056E009A9D22 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
IBSC_MODULE = BinaryWatch_Extension;
INFOPLIST_FILE = BinaryWatch/Info.plist;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.Binary.watchkitapp;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 5.0;
};
name = Debug;
};
3EEAFD9F20F1056E009A9D22 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
IBSC_MODULE = BinaryWatch_Extension;
INFOPLIST_FILE = BinaryWatch/Info.plist;
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.Binary.watchkitapp;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 5.0;
};
name = Release;
};
3EEAFDA020F1056E009A9D22 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = "BinaryWatch Extension/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.Binary.watchkitapp.watchkitextension;
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 5.0;
};
name = Debug;
};
3EEAFDA120F1056E009A9D22 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = "BinaryWatch Extension/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = me.leavez.Binary.watchkitapp.watchkitextension;
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@ -365,6 +639,24 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3EEAFDA220F1056E009A9D22 /* Build configuration list for PBXNativeTarget "BinaryWatch Extension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3EEAFDA020F1056E009A9D22 /* Debug */,
3EEAFDA120F1056E009A9D22 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3EEAFDA420F1056E009A9D22 /* Build configuration list for PBXNativeTarget "BinaryWatch" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3EEAFD9E20F1056E009A9D22 /* Debug */,
3EEAFD9F20F1056E009A9D22 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 3E83E31A207BC00E0057855A /* Project object */;

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : "<=145"
},
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : ">145"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,28 @@
{
"assets" : [
{
"idiom" : "watch",
"filename" : "Circular.imageset",
"role" : "circular"
},
{
"idiom" : "watch",
"filename" : "Extra Large.imageset",
"role" : "extra-large"
},
{
"idiom" : "watch",
"filename" : "Modular.imageset",
"role" : "modular"
},
{
"idiom" : "watch",
"filename" : "Utilitarian.imageset",
"role" : "utilitarian"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : "<=145"
},
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : ">145"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : "<=145"
},
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : ">145"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : "<=145"
},
{
"idiom" : "watch",
"scale" : "2x",
"screen-width" : ">145"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,21 @@
//
// ExtensionDelegate.swift
// BinaryWatch Extension
//
// Created by Gao on 2018/7/7.
// Copyright © 2018 me.leavez. All rights reserved.
//
import WatchKit
class ExtensionDelegate: NSObject, WKExtensionDelegate {
func applicationDidFinishLaunching() {
// Perform any final initialization of your application.
}
func applicationDidBecomeActive() {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>BinaryWatch Extension</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>WKAppBundleIdentifier</key>
<string>me.leavez.Binary.watchkitapp</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.watchkit</string>
</dict>
<key>WKExtensionDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).ExtensionDelegate</string>
</dict>
</plist>

View File

@ -0,0 +1,31 @@
//
// InterfaceController.swift
// BinaryWatch Extension
//
// Created by Gao on 2018/7/7.
// Copyright © 2018 me.leavez. All rights reserved.
//
import WatchKit
import Foundation
class InterfaceController: WKInterfaceController {
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,67 @@
{
"images" : [
{
"size" : "24x24",
"idiom" : "watch",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "38mm"
},
{
"size" : "27.5x27.5",
"idiom" : "watch",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "42mm"
},
{
"size" : "29x29",
"idiom" : "watch",
"role" : "companionSettings",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "watch",
"role" : "companionSettings",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "watch",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "38mm"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "longLook",
"subtype" : "42mm"
},
{
"size" : "86x86",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "38mm"
},
{
"size" : "98x98",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "42mm"
},
{
"idiom" : "watch-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="11134" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="AgC-eL-Hgc">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="11055"/>
</dependencies>
<scenes>
<!--Interface Controller-->
<scene sceneID="aou-V4-d1y">
<objects>
<controller id="AgC-eL-Hgc" customClass="InterfaceController" customModuleProvider="target"/>
</objects>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Binary</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>WKCompanionAppBundleIdentifier</key>
<string>me.leavez.Binary</string>
<key>WKWatchKitApp</key>
<true/>
</dict>
</plist>

7
test/Gemfile Normal file
View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
source "https://rubygems.org"
gem 'cocoapods', '1.6.1'
gem 'cocoapods-binary', :path => "../"

View File

@ -4,6 +4,7 @@ import sys
def wrapper(content):
return """
platform :ios, '9.0'
inhibit_all_warnings!
use_frameworks!
plugin "cocoapods-binary"
@ -25,6 +26,12 @@ def save_to_podfile(text):
file.write(text[1])
file.close()
path = os.path.dirname(os.path.abspath(__file__))
path += "/BinaryWatch Extension/import.swift"
file = open(path, "w+")
file.write( "" if len(text) <= 2 else text[2])
file.close()
def initial():
@ -36,6 +43,9 @@ pod "Masonry"
"""),
"""
import Masonry
class A {
let d = UIView().mas_top
}
""")
def addSwiftPod():
@ -49,6 +59,10 @@ pod "Literal", :binary => true
"""
import RxCocoa
import Literal
class A {
let a: CGRect = [1,2,3,4]
func dd() { NSObject().rx.observe(CGRect.self, "frame") }
}
""")
def revertToSourceCode():
@ -61,7 +75,13 @@ pod "Literal"
"""),
"""
import RxCocoa
import RxSwift
import Literal
class A {
let a: CGRect = [1,2,3,4]
let b = Observable.just(1)
func dd() { NSObject().rx.observe(CGRect.self, "frame") }
}
""")
def addDifferentNamePod():
@ -77,6 +97,11 @@ pod "lottie-ios", :binary => true
import Masonry
import Literal
import Lottie
class A {
let a: CGRect = [1,2,3,4]
let a2 = AnimationView.self
let d = UIView().mas_top
}
""")
@ -93,6 +118,12 @@ import Masonry
import Literal
import Lottie
import AFNetworking
class A {
let a: CGRect = [1,2,3,4]
let a2 = AnimationView.self
let b = AFNetworkReachabilityManager()
let d = UIView().mas_top
}
""")
def addVendoredLibPod():
@ -107,6 +138,11 @@ pod "GrowingIO", :binary => true
import Literal
import AFNetworking
import Instabug
class A {
let a: CGRect = [1,2,3,4]
let b = AFNetworkReachabilityManager()
let c = Instabug.self
}
""")
def deleteAPod():
@ -118,6 +154,10 @@ pod "AFNetworking/Reachability", :binary => true
"""
import Literal
import AFNetworking
class A {
let a: CGRect = [1,2,3,4]
let b = AFNetworkReachabilityManager()
}
""")
def universalFlag():
@ -131,9 +171,67 @@ pod "AFNetworking/Reachability"
"""
import Literal
import AFNetworking
class A {
let a: CGRect = [1,2,3,4]
let b = AFNetworkReachabilityManager()
}
""")
def multiplePlatforms():
return (wrapper(
"""
pod "Literal", :binary => true
pod "AFNetworking/Serialization", :binary => true
end
target 'BinaryWatch Extension' do
platform :watchos
pod "AFNetworking/Serialization", :binary => true
""") ,
"""
import Literal
import AFNetworking
class A {
let a: CGRect = [1,2,3,4]
func dd() { _ = AFURLRequestSerializationErrorDomain }
}
""",
"""
import AFNetworking
class A {
func dd() { _ = AFURLRequestSerializationErrorDomain }
}
"""
)
def multiplePlatformsWithALLFlag():
return (wrapper(
"""
all_binary!
pod "Literal"
pod "AFNetworking/Serialization"
end
target 'BinaryWatch Extension' do
platform :watchos
pod "AFNetworking/Serialization"
""") ,
"""
import Literal
import AFNetworking
class A {
let a: CGRect = [1,2,3,4]
func dd() { _ = AFURLRequestSerializationErrorDomain }
}
""",
"""
import AFNetworking
class A {
func dd() { _ = AFURLRequestSerializationErrorDomain }
}
"""
)
if __name__ == "__main__":

BIN
test/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -2,49 +2,16 @@
set -e
build() {
xcodebuild -workspace Binary.xcworkspace -scheme Binary ONLY_ACTIVE_ARCH=YES CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -quiet || exit 1
}
xcodebuild -workspace Binary.xcworkspace -scheme Binary ONLY_ACTIVE_ARCH=YES CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO -quiet || exit 1
}
rm -rf Pods
python change_podfile.py "initial"
pod install
build
cases=("initial" "addSwiftPod" "revertToSourceCode" "addDifferentNamePod" "addSubPod" "deleteAPod" "addVendoredLibPod" "universalFlag" "multiplePlatforms" "multiplePlatformsWithALLFlag")
for action in ${cases[@]}; do
python change_podfile.py ${action}
bundle exec pod install
build
done
#
python change_podfile.py "addSwiftPod"
pod install
build
#
python change_podfile.py "revertToSourceCode"
pod install
build
#
python change_podfile.py "addDifferentNamePod"
pod install
build
#
python change_podfile.py "addSubPod"
pod install
build
#
python change_podfile.py "deleteAPod"
pod install
build
#
python change_podfile.py "addVendoredLibPod"
pod install
build
#
python change_podfile.py "universalFlag"
pod install
build
#
exit 0