cocoapods-project-gen 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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: []