cocoapods-project-gen 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8224b3941957448267846730698368b63e05c21813a8785cef0077ffb5ea56b2
4
+ data.tar.gz: 525e97837422369163770a4e56fd3baadc67edeea2c5b156505e91c6325b78df
5
+ SHA512:
6
+ metadata.gz: 2e62a1df71643dcc9f824c2a330e6d30d4c8854011e5d1b6b6bdcb696349d1766e288bde42d1e36730a0a988cf7bfd60e5d2c59cfbc7b0215bbce51536cde705
7
+ data.tar.gz: 9b0e65439b421036a9ef85bc2983edb34f16c3592cdbce370865387c57e47efc04e71b50dcbed185ceb873a651f17e8e4058baf2cf9599ccebbd8c9deea2e4cd
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Cat1237
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # cocoapods-project-gen
2
+
3
+ [![License MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/Cat1237/cocoapods-project-gen/main/LICENSE) 
4
+
5
+ A gem which can gen cocoapods project.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'cocoapods-project-gen'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```shell
18
+ # bundle install
19
+ $ bundle install
20
+ ```
21
+
22
+ Or install it yourself as:
23
+
24
+ ```shell
25
+ # gem install
26
+ $ gem install cocoapods-project-gen
27
+ ```
28
+ ### Quickstart
29
+
30
+ To begin gen an cocoapods project start by create an `ProjectGenerator`:
31
+
32
+ ```ruby
33
+ require 'cocoapods-project-gen'
34
+ podspecs = Pathname.glob(File.expand_path("./Resources/AFNetworking-master", __dir__) + '/*.podspec{.json,}')
35
+ out_put = File.expand_path("./Resources/output", __dir__)
36
+ gen = ProjectGen::ProjectGenerator.new_from_local(podspecs, [])
37
+ gen.generate!(out_put) do |platforms, pod_targets, validated|
38
+ p platforms, pod_targets, validated
39
+ end
40
+ ```
41
+
42
+ or use this way:
43
+
44
+ ```ruby
45
+ require 'cocoapods-project-gen'
46
+
47
+ product_type = :dynamic_framework
48
+ use_module = true
49
+ include_podspecs = []
50
+ swift_version = '4.2'
51
+ configuration = :release
52
+ generator = ProjectGen::ProjectGenerator.new(include_podspecs.first, @sources, @platforms)
53
+ generator.local = false
54
+ generator.no_clean = false
55
+ generator.allow_warnings = true
56
+ generator.no_subspecs = true
57
+ generator.only_subspec = false
58
+ generator.use_frameworks = product_type == :dynamic_framework
59
+ generator.use_static_frameworks = product_type == :framework
60
+ generator.use_modular_headers = use_module
61
+ generator.skip_import_validation = true
62
+ generator.external_podspecs = include_podspecs.drop(1)
63
+ generator.swift_version = swift_version
64
+ generator.configuration = configuration
65
+ generator.skip_tests = true
66
+ begin
67
+ generator.generate!(spec_root) do |platform, pod_targets, validated|
68
+ raise 'Could not generator App.xcodeproj' unless validated
69
+
70
+ end
71
+ rescue StandardError => e
72
+ raise Pod::Informative, "The `#{@include_podspecs.join(' ')}` specification does not validate." \
73
+ "\n\n#{e.message}"
74
+ end
75
+ ```
76
+
77
+ ## Contributing
78
+
79
+ Bug reports and pull requests are welcome on GitHub at [cocoapods-project-gen](https://github.com/Cat1237/cocoapods-project-gen). This project is intended to be a safe, welcoming space for collaboration.
80
+
81
+ ## License
82
+
83
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
84
+
85
+ ## Code of Conduct
86
+
87
+ Everyone interacting in the yaml-vfs project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Cat1237/cocoapods-project-gen/main/CODE_OF_CONDUCT.md).
@@ -0,0 +1,3 @@
1
+ module ProjectGen
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,193 @@
1
+ require 'cocoapods/validator'
2
+ require 'cocoapods-project-gen/gen/swift_module_helper'
3
+ require 'fileutils'
4
+
5
+ module ProjectGen
6
+ class ProjectGenerator < Pod::Validator
7
+ include ProjectGen::SwiftModule
8
+
9
+ # Initialize a new instance
10
+ #
11
+ # @param [Array<Specification, Pathname, String>] podspecs
12
+ # the Specifications or the paths of the `podspec` files to used.
13
+ #
14
+ # @param [Array<String>] source_urls
15
+ # the Source URLs to use in creating a {Podfile}.
16
+ #
17
+ # @param [Array<String>] platforms
18
+ # the platforms to used.
19
+ #
20
+ # @param [Symbol] either :framework or :static_library, depends on
21
+ # #build_as_framework?.
22
+ #
23
+ # @param [Symbol] The name of the build configuration.
24
+ #
25
+ # @param [String] the SWIFT_VERSION within the .swift-version file or nil.
26
+ #
27
+ # @param [Boolean] Whether modular headers should be used for the installation.
28
+ #
29
+ def self.new_from_local(podspecs, source_urls, platforms = [], product_type = :framework, configuration = :release, swift_version = nil, use_modular_headers: false)
30
+ generator = new(podspecs[0], source_urls, platforms)
31
+ generator.local = false
32
+ generator.no_subspecs = true
33
+ generator.only_subspec = nil
34
+ generator.no_clean = false
35
+ generator.allow_warnings = true
36
+ generator.use_frameworks = product_type == :dynamic_framework
37
+ generator.use_static_frameworks = product_type == :framework
38
+ generator.skip_import_validation = true
39
+ generator.external_podspecs = podspecs.drop(1)
40
+ generator.configuration = configuration
41
+ generator.skip_tests = true
42
+ generator.use_modular_headers = use_modular_headers
43
+ generator.swift_version = swift_version unless swift_version.nil?
44
+ generator
45
+ end
46
+
47
+ # Create app project
48
+ #
49
+ # @param [String, Pathname] dir the temporary directory used by the Gen.
50
+ #
51
+ # @param [block<platform, pod_targets, valid>] &block the block to execute inside the lock.
52
+ #
53
+ def generate!(dir, &block)
54
+ dir = Pathname(dir)
55
+ @results = []
56
+ # Replace default spec with a subspec if asked for
57
+ a_spec = spec
58
+ if spec && @only_subspec
59
+ subspec_name = @only_subspec.start_with?(spec.root.name) ? @only_subspec : "#{spec.root.name}/#{@only_subspec}"
60
+ a_spec = spec.subspec_by_name(subspec_name, true, true)
61
+ @subspec_name = a_spec.name
62
+ end
63
+ @validation_dir = dir
64
+ Pod::UI.print " -> #{a_spec ? a_spec.name : file.basename}\r" unless config.silent?
65
+ $stdout.flush
66
+ send(:perform_linting) if respond_to?(:perform_linting)
67
+ install(a_spec, dir, &block) if a_spec && !quick
68
+ Pod::UI.puts ' -> '.send(result_color) << (a_spec ? a_spec.to_s : file.basename.to_s)
69
+ print_results
70
+ end
71
+
72
+ def pod_targets
73
+ @installer.pod_targets
74
+ end
75
+
76
+ private
77
+
78
+ # Perform analysis for a given spec (or subspec)
79
+ #
80
+ def install(spec, dir, &block)
81
+ if spec.non_library_specification?
82
+ error('spec', "Validating a non library spec (`#{spec.name}`) is not supported.")
83
+ return false
84
+ end
85
+ platforms = send(:platforms_to_lint, spec)
86
+ valid = platforms.send(fail_fast ? :all? : :each) do |platform|
87
+ Pod::UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed
88
+ @consumer = spec.consumer(platform)
89
+ c_method = %i[setup_validation_environment create_app_project handle_local_pod
90
+ check_file_patterns install_pod validate_swift_version
91
+ add_app_project_import validate_vendored_dynamic_frameworks]
92
+ begin
93
+ c_method.each { |m| send(m) }
94
+ valid = validated?
95
+ end
96
+ block.call(platform, pod_targets, valid) unless block&.nil?
97
+ return false if fail_fast && !valid
98
+
99
+ generate_subspec(spec, dir, &block) unless @no_subspecs
100
+ rescue StandardError => e
101
+ message = e.to_s
102
+ raise Pod::Informative, "Encountered an unknown error\n\n#{message})\n\n#{e.backtrace * "\n"}"
103
+ end
104
+ end
105
+
106
+ def generate_subspec(spec, dir, &block)
107
+ spec.subspecs.reject(&:non_library_specification?).send(fail_fast ? :all? : :each) do |subspec|
108
+ @subspec_name = subspec.name
109
+ install(subspec, dir, &block)
110
+ end
111
+ end
112
+
113
+ def handle_local_pod
114
+ sandbox = Pod::Sandbox.new(@validation_dir + 'Pods')
115
+ test_spec_names = consumer.spec.test_specs.select do |ts|
116
+ ts.supported_on_platform?(consumer.platform_name)
117
+ end.map(&:name)
118
+ podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, test_spec_names,
119
+ use_modular_headers, use_static_frameworks)
120
+
121
+ @installer = Pod::Installer.new(sandbox, podfile)
122
+ @installer.use_default_plugins = false
123
+ @installer.has_dependencies = !spec.dependencies.empty?
124
+ %i[prepare resolve_dependencies download_dependencies clean_pod_sources write_lockfiles].each do |m|
125
+ case m
126
+ when :clean_pod_sources
127
+ copy_and_clean(sandbox)
128
+ podspecs.each { |s| sandbox.development_pods.delete(s.name) }
129
+ @installer.send(m)
130
+ else
131
+ @installer.send(m)
132
+ next unless m == :resolve_dependencies
133
+
134
+ podspecs.each { |s| sandbox.store_local_path(s.name, s.defined_in_file, absolute?(s.defined_in_file)) }
135
+ end
136
+ end
137
+ library_targets = pod_targets.select { |target| target.build_as_library? }
138
+ add_swift_library_compatibility_header(library_targets)
139
+ @file_accessor = pod_targets.flat_map(&:file_accessors).find do |fa|
140
+ fa.spec.name == consumer.spec.name
141
+ end
142
+ end
143
+
144
+ def podspecs
145
+ ps = [file]
146
+ ps += external_podspecs.map { |pa| Pathname.new(pa) } if external_podspecs
147
+ ps += include_podspecs.map { |pa| Pathname.new(pa) } if include_podspecs
148
+ ps.uniq.map { |path| Pod::Specification.from_file(path) }
149
+ end
150
+
151
+ # @return [Bool]
152
+ #
153
+ def absolute?(path)
154
+ Pathname(path).absolute? || path.to_s.start_with?('~')
155
+ end
156
+
157
+ def group_subspecs_by_platform(spec)
158
+ specs_by_platform = {}
159
+ [spec, *spec.recursive_subspecs].each do |ss|
160
+ ss.available_platforms.each do |platform|
161
+ specs_by_platform[platform] ||= []
162
+ specs_by_platform[platform] << ss
163
+ end
164
+ end
165
+ specs_by_platform
166
+ end
167
+
168
+ def copy(source, destination, specs_by_platform)
169
+ path_list = Pod::Sandbox::PathList.new(source)
170
+ file_accessors = specs_by_platform.flat_map do |platform, specs|
171
+ specs.flat_map { |spec| Pod::Sandbox::FileAccessor.new(path_list, spec.consumer(platform)) }
172
+ end
173
+ used_files = Pod::Sandbox::FileAccessor.all_files(file_accessors)
174
+ used_files.each do |path|
175
+ path = Pathname(path)
176
+ n_path = destination.join(path.relative_path_from(source))
177
+ n_path.dirname.mkpath
178
+ FileUtils.cp_r(path, n_path.dirname)
179
+ end
180
+ end
181
+
182
+ def copy_and_clean(sandbox)
183
+ podspecs.each do |spec|
184
+ destination = config.sandbox_root + spec.name
185
+ source = sandbox.pod_dir(spec.name)
186
+ specs_by_platform = group_subspecs_by_platform(spec)
187
+ destination.parent.mkpath
188
+ FileUtils.rm_rf(destination)
189
+ copy(source, destination, specs_by_platform)
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,52 @@
1
+ require 'cocoapods'
2
+
3
+ module ProjectGen
4
+ module SwiftModule
5
+ COPY_LIBRARY_SWIFT_HEADERS = 'Copy-Library-Swift-Headers'
6
+ private_constant :COPY_LIBRARY_SWIFT_HEADERS
7
+
8
+ # Adds a shell script phase, intended only for library targets that contain swift,
9
+ # to copy the ObjC compatibility header (the -Swift.h file that the swift compiler generates)
10
+ # to the built products directory. Additionally, the script phase copies the module map, appending a `.Swift`
11
+ # submodule that references the (moved) compatibility header. Since the module map has been moved, the umbrella header
12
+ # is _also_ copied, so that it is sitting next to the module map. This is necessary for a successful archive build.
13
+ #
14
+ # @param [PBXNativeTarget] native_target
15
+ # the native target to add the Swift static library script phase into.
16
+ #
17
+ # @return [Void]
18
+ #
19
+ def add_swift_library_compatibility_header(targets)
20
+ targets.each do |target|
21
+ relative_module_map_path = target.module_map_path.relative_path_from(target.sandbox.root)
22
+ relative_umbrella_header_path = target.umbrella_header_path.relative_path_from(target.sandbox.root)
23
+ shell_script = <<-SH.strip_heredoc
24
+ COMPATIBILITY_HEADER_ROOT_PATH="${SRCROOT}/${PRODUCT_MODULE_NAME}/#{COPY_LIBRARY_SWIFT_HEADERS}"
25
+ COPY_MODULE_MAP_PATH="${COMPATIBILITY_HEADER_ROOT_PATH}/${PRODUCT_MODULE_NAME}.modulemap"
26
+ ditto "${PODS_ROOT}/#{relative_module_map_path}" "${COPY_MODULE_MAP_PATH}"
27
+ UMBRELLA_HEADER_PATH="${PODS_ROOT}/#{relative_umbrella_header_path}"
28
+ if test -f "$UMBRELLA_HEADER_PATH"; then
29
+ ditto "$UMBRELLA_HEADER_PATH" "${COMPATIBILITY_HEADER_ROOT_PATH}"
30
+ fi
31
+ SH
32
+
33
+ target.root_spec.script_phases ||= []
34
+ target.root_spec.script_phases += [{ name: 'Copy Copy generated module header', script: shell_script }]
35
+ next unless target.uses_swift?
36
+
37
+ shell_script = <<-SH.strip_heredoc
38
+ COMPATIBILITY_HEADER_ROOT_PATH="${SRCROOT}/${PRODUCT_MODULE_NAME}/#{COPY_LIBRARY_SWIFT_HEADERS}"
39
+ COPY_COMPATIBILITY_HEADER_PATH="${COMPATIBILITY_HEADER_ROOT_PATH}/${PRODUCT_MODULE_NAME}-Swift.h"#{' '}
40
+ COPY_MODULE_MAP_PATH="${COMPATIBILITY_HEADER_ROOT_PATH}/${PRODUCT_MODULE_NAME}.modulemap"
41
+ ditto "${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h" "${COPY_COMPATIBILITY_HEADER_PATH}"#{' '}
42
+ ditto "${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.swiftmodule" "${COMPATIBILITY_HEADER_ROOT_PATH}/${PRODUCT_MODULE_NAME}.swiftmodule"#{' '}
43
+ printf "\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\"${PRODUCT_MODULE_NAME}-Swift.h\\"\\n requires objc\\n}\\n" >> "${COPY_MODULE_MAP_PATH}"
44
+ SH
45
+ target.root_spec.script_phases += [{
46
+ name: 'Copy Copy generated compatibility header',
47
+ script: shell_script
48
+ }]
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ module ProjectGen
2
+ require 'cocoapods'
3
+ require 'cocoapods-project-gen/gem_version'
4
+ # autoload registers a file path to be loaded the first time
5
+ # that a specified module or class is accessed in the namespace of the calling module or class.
6
+ autoload :ProjectGenerator, 'cocoapods-project-gen/gen/project_gen'
7
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-project-gen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cat1237
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cocoapods
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.10.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.10.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ description: cocoapods project gen
42
+ email:
43
+ - wangson1237@outlook.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE
49
+ - README.md
50
+ - lib/cocoapods-project-gen.rb
51
+ - lib/cocoapods-project-gen/gem_version.rb
52
+ - lib/cocoapods-project-gen/gen/project_gen.rb
53
+ - lib/cocoapods-project-gen/gen/swift_module_helper.rb
54
+ homepage: https://github.com/Cat1237/cocoapods-project-gen.git
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '2.6'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.1.6
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: cocoapods project gen.
77
+ test_files: []