cocoapods-hmap-prebuilt 0.0.1
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 +7 -0
- data/LICENSE +22 -0
- data/README.md +40 -0
- data/bin/hmap-prebuilt-read +10 -0
- data/bin/hmap-prebuilt-write +10 -0
- data/lib/cocoapods-hmap-prebuilt.rb +13 -0
- data/lib/cocoapods-hmap-prebuilt/command/hmap_reader.rb +39 -0
- data/lib/cocoapods-hmap-prebuilt/command/hmap_writer.rb +46 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_exceptions.rb +0 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_file.rb +0 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_file_reader.rb +91 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_file_writer.rb +148 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_helper.rb +85 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_struct.rb +264 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_utils.rb +136 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_version.rb +3 -0
- data/lib/cocoapods-hmap-prebuilt/hmap_view.rb +29 -0
- data/lib/cocoapods_plugin.rb +11 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 06ec400c0386357e5211eebf6b5a14f9698e652c2f02349d393652b079528f35
|
4
|
+
data.tar.gz: 1e8b99f1e32e4086a24300566d0bcadb7b5395dfc19d58bf516878c80f50d68b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4bd94eb184b1f0c5d0fe2234001bdea13f38a31c3acea71d98b9a70e01cdf737fddc2f47118e42092846c84ffabdc3c03125576eb521e499e40fadd6ae164f83
|
7
|
+
data.tar.gz: 96017f250188e500d55cb8258885db82fd779b26643fafbb039c7592a7635275040bc99c3149deb54fae7f633df4f5b791cfd48f8c35540786a9ddba2bd4ce52
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2021 EricLou <499304609@qq.com>
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# cocoapods-hmap-prebuilt
|
2
|
+
|
3
|
+
A description of cocoapods-hmap-prebuilt.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install cocoapods-hmap-prebuilt
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
The command should be executed in directory that contains podfile.
|
12
|
+
|
13
|
+
```shell
|
14
|
+
# write the hmap file to podfile/Pods/Headers/HMap
|
15
|
+
$ pod hmap-writer
|
16
|
+
|
17
|
+
# write the hmap file to /project/dir/Pods/Headers/HMap
|
18
|
+
$ pod hmap-writer --project-directory=/project/dir/
|
19
|
+
|
20
|
+
# write the hmap file to /project/dir/Pods/Headers/HMap and no save origin [HEADER_SEARCH_PATHS]
|
21
|
+
$ pod hmap-writer --project-directory=/project/dir/ --nosave-origin-header-search-paths
|
22
|
+
|
23
|
+
# cleanup the hmap file
|
24
|
+
$ pod hmap-writer --clean-hmap
|
25
|
+
|
26
|
+
# read the hmap file from /hmap/dir/file
|
27
|
+
$ pod hmap-reader --hmap-path=/hmap/dir/file
|
28
|
+
```
|
29
|
+
|
30
|
+
At same time, you can put this line in your podfile:
|
31
|
+
|
32
|
+
```rb
|
33
|
+
plugin 'cocoapods-hmap-prebuilt'
|
34
|
+
```
|
35
|
+
|
36
|
+
## Command Line Tool
|
37
|
+
|
38
|
+
Installing the 'cocoapods-hmap-prebuilt' gem will also install two command-line tool `hmap-prebuilt-read` and `hmap-prebuilt-write` which you can use to generate header map file and read hmap file.
|
39
|
+
|
40
|
+
For more information consult `hmap-prebuilt-read --help` or `hmap-prebuilt-write --help`.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# The primary namespace for cocoapods-hmap-prebuilt.
|
2
|
+
module HMap
|
3
|
+
require_relative 'cocoapods-hmap-prebuilt/hmap_version'
|
4
|
+
require_relative 'cocoapods-hmap-prebuilt/hmap_view'
|
5
|
+
require_relative 'cocoapods-hmap-prebuilt/hmap_struct'
|
6
|
+
require_relative 'cocoapods-hmap-prebuilt/hmap_utils'
|
7
|
+
require_relative 'cocoapods-hmap-prebuilt/hmap_helper'
|
8
|
+
require_relative 'cocoapods-hmap-prebuilt/hmap_exceptions'
|
9
|
+
|
10
|
+
autoload :HMapFileReader, 'cocoapods-hmap-prebuilt/hmap_file_reader'
|
11
|
+
autoload :HMapFileWriter, 'cocoapods-hmap-prebuilt/hmap_file_writer'
|
12
|
+
autoload :HMapFile, 'cocoapods-hmap-prebuilt/hmap_file'
|
13
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'cocoapods-hmap-prebuilt'
|
2
|
+
require 'cocoapods'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Command
|
6
|
+
class HMapReader < Command
|
7
|
+
self.summary = 'Read mapfile and puts result.'
|
8
|
+
|
9
|
+
self.description = <<-DESC
|
10
|
+
Read mapfile and puts result, header, buckets, string_table.
|
11
|
+
DESC
|
12
|
+
|
13
|
+
def initialize(argv)
|
14
|
+
super
|
15
|
+
hmap_file_path = argv.option('hmap-path')
|
16
|
+
@hmap_file_path = Pathname.new(hmap_file_path).expand_path unless hmap_file_path.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate!
|
20
|
+
super
|
21
|
+
banner! if help?
|
22
|
+
raise '[ERROR]: --hmap-path no set'.red unless File.exist?(@hmap_file_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.options
|
26
|
+
[
|
27
|
+
['--hmap-path=/hmap/dir/file', 'The path of the hmap file']
|
28
|
+
].concat(super)
|
29
|
+
end
|
30
|
+
|
31
|
+
def run
|
32
|
+
UI.section "\n[hmap-reader] start..............\n".yellow do
|
33
|
+
HMap::MapFileReader.new(@hmap_file_path)
|
34
|
+
end
|
35
|
+
UI.puts("\n[hmap-reader] finish..............\n".yellow)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'cocoapods-hmap-prebuilt'
|
2
|
+
require 'cocoapods'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Command
|
6
|
+
class HMapWriter < Command
|
7
|
+
self.summary = 'Analyzes the dependencies and gen each dependencie mapfile.'
|
8
|
+
|
9
|
+
self.description = <<-DESC
|
10
|
+
Analyzes the dependencies of any cocoapods projects and gen each dependencie mapfile.
|
11
|
+
DESC
|
12
|
+
|
13
|
+
def initialize(argv)
|
14
|
+
super
|
15
|
+
project_directory = argv.option('project-directory')
|
16
|
+
@save_origin_header_search_paths = !argv.flag?('nosave-origin-header-search-paths', false)
|
17
|
+
@clean_hmap = argv.flag?('clean-hmap', false)
|
18
|
+
|
19
|
+
return if project_directory.nil?
|
20
|
+
|
21
|
+
@project_directory = Pathname.new(project_directory).expand_path
|
22
|
+
config.installation_root = @project_directory
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate!
|
26
|
+
super
|
27
|
+
verify_podfile_exists!
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.options
|
31
|
+
[
|
32
|
+
['--project-directory=/project/dir/', 'The path to the root of the project directory'],
|
33
|
+
['--nosave-origin-header-search-paths', 'This option will not save xcconfig origin [HEADER_SEARCH_PATHS] and put hmap file first'],
|
34
|
+
['--clean-hmap', 'This option will clean up all hmap-prebuilt setup for hmap.']
|
35
|
+
].concat(super)
|
36
|
+
end
|
37
|
+
|
38
|
+
def run
|
39
|
+
UI.section "\n[hmap-prebuilt] start.............." do
|
40
|
+
HMap::HMapFileWriter.new(@save_origin_header_search_paths, @clean_hmap)
|
41
|
+
end
|
42
|
+
UI.puts('[hmap-prebuilt] finish..............')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module HMap
|
2
|
+
|
3
|
+
class HMapFileReader
|
4
|
+
# @return [String, nil] the filename loaded from, or nil if loaded from a binary
|
5
|
+
# string
|
6
|
+
attr_reader :filename
|
7
|
+
# # @return [Hash] any parser options that the instance was created with
|
8
|
+
# attr_reader :options
|
9
|
+
|
10
|
+
# @return true/false the swapped of the mapfile
|
11
|
+
attr_reader :swapped
|
12
|
+
|
13
|
+
# @return [HMap::HMapHeader]
|
14
|
+
attr_reader :header
|
15
|
+
|
16
|
+
# @return [Hash<HMap::HMapBucket => HMap::HMapBucketStr>] an array of the file's bucktes
|
17
|
+
# @note bucktes are provided in order of ascending offset.
|
18
|
+
attr_reader :bucktes
|
19
|
+
|
20
|
+
def initialize(path)
|
21
|
+
raise ArgumentError, "#{path}: no such file" unless File.file?(path)
|
22
|
+
|
23
|
+
@filename = path
|
24
|
+
@raw_data = File.open(@filename, 'rb', &:read)
|
25
|
+
populate_fields
|
26
|
+
puts description
|
27
|
+
end
|
28
|
+
|
29
|
+
# Populate the instance's fields with the raw HMap data.
|
30
|
+
# @return [void]
|
31
|
+
# @note This method is public, but should (almost) never need to be called.
|
32
|
+
def populate_fields
|
33
|
+
@header = populate_hmap_header
|
34
|
+
string_t = @raw_data[header.strings_offset..-1]
|
35
|
+
@bucktes = populate_buckets do |bucket|
|
36
|
+
bucket_s = bucket.to_a.map do |key|
|
37
|
+
string_t[key..-1].match(/[^\0]+/)[0]
|
38
|
+
end
|
39
|
+
HMapBucketStr.new(*bucket_s)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# The file's HMapheader structure.
|
44
|
+
# @return [HMap::HMapHeader]
|
45
|
+
# @raise [TruncatedFileError] if the file is too small to have a valid header
|
46
|
+
# @api private
|
47
|
+
def populate_hmap_header
|
48
|
+
raise TruncatedFileError if @raw_data.size < HMapHeader.bytesize + 8 * HMapBucket.bytesize
|
49
|
+
|
50
|
+
populate_and_check_magic
|
51
|
+
HMapHeader.new_from_bin(swapped, @raw_data[0, HMapHeader.bytesize])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Read just the file's magic number and check its validity.
|
55
|
+
# @return [Integer] the magic
|
56
|
+
# @raise [MagicError] if the magic is not valid HMap magic
|
57
|
+
# @api private
|
58
|
+
def populate_and_check_magic
|
59
|
+
magic = @raw_data[0..3].unpack1('N')
|
60
|
+
raise MagicError, magic unless Utils.magic?(magic)
|
61
|
+
|
62
|
+
version = @raw_data[4..5].unpack1('n')
|
63
|
+
@swapped = Utils.swapped_magic?(magic, version)
|
64
|
+
end
|
65
|
+
|
66
|
+
# All buckets in the file.
|
67
|
+
# @return [Array<HMap::HMapBucket>] an array of buckets
|
68
|
+
# @api private
|
69
|
+
def populate_buckets
|
70
|
+
bucket_offset = header.class.bytesize
|
71
|
+
bucktes = []
|
72
|
+
header.num_buckets.times do |i|
|
73
|
+
bucket = HMapBucket.new_from_bin(swapped, @raw_data[bucket_offset, HMapBucket.bytesize])
|
74
|
+
bucket_offset += HMapBucket.bytesize
|
75
|
+
next if bucket.key == HEADER_CONST[:HMAP_EMPTY_BUCKT_KEY]
|
76
|
+
|
77
|
+
bucktes[i] = { bucket => yield(bucket) }
|
78
|
+
end
|
79
|
+
bucktes
|
80
|
+
end
|
81
|
+
|
82
|
+
def description
|
83
|
+
sum = " Header map: #{filename}\n" + header.description
|
84
|
+
bucktes.each_with_index do |buckte_h, index|
|
85
|
+
sum += "\t- Bucket: #{index}" + Utils.safe_encode(buckte_h.values[0].description, 'UTF-8') unless buckte_h.nil?
|
86
|
+
sum
|
87
|
+
end
|
88
|
+
sum
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'cocoapods'
|
2
|
+
|
3
|
+
module HMap
|
4
|
+
|
5
|
+
HMAP_DIR_NAME = 'HMap'
|
6
|
+
|
7
|
+
# mapfile type
|
8
|
+
# @note public => pods public,
|
9
|
+
# private => pods private,
|
10
|
+
# all => public + private + extra.
|
11
|
+
# @api private
|
12
|
+
HMMAP_TYPE = {
|
13
|
+
public_header_files: 'public',
|
14
|
+
private_header_files: 'private',
|
15
|
+
all_files: 'all'
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
HEAD_SEARCH_PATHS = 'HEADER_SEARCH_PATHS'
|
19
|
+
|
20
|
+
# Helper module which returns handle method from HMapFileWriter.
|
21
|
+
class HMapFileWriter
|
22
|
+
def initialize(save_origin_header_search_paths, clean_hmap)
|
23
|
+
config = Pod::Config.instance
|
24
|
+
analyze = Helper::PodHelper.pod_analyze(config)
|
25
|
+
hmap_dir = hmap_dir(config)
|
26
|
+
targets = analyze.targets
|
27
|
+
pod_targets = analyze.pod_targets
|
28
|
+
clean_hmap(clean_hmap, hmap_dir, targets, pod_targets)
|
29
|
+
return if clean_hmap
|
30
|
+
|
31
|
+
@save_origin_header_search_paths = save_origin_header_search_paths
|
32
|
+
gen_hmapfile(targets, pod_targets, hmap_dir)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def hmap_dir(config)
|
38
|
+
hmap_dir = File.join(config.sandbox.headers_root, HMAP_DIR_NAME)
|
39
|
+
puts "HMap dir: #{hmap_dir}"
|
40
|
+
hmap_dir
|
41
|
+
end
|
42
|
+
|
43
|
+
def clean_hmap(clean_hmap, hmap_dir, *targets)
|
44
|
+
return unless clean_hmap
|
45
|
+
FileUtils.rm_rf(hmap_dir)
|
46
|
+
targets.each do |tg|
|
47
|
+
Utils.clean_target_build_setting(tg, HEAD_SEARCH_PATHS)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def gen_hmapfile(targets, pod_targets, hmap_dir)
|
52
|
+
puts('Inspecting targets to integrate ')
|
53
|
+
merge_all_pods_target_headers_mapfile(pod_targets, hmap_dir)
|
54
|
+
merge_all_target_public_mapfile(targets, hmap_dir)
|
55
|
+
create_each_target_mapfile(pod_targets, hmap_dir)
|
56
|
+
end
|
57
|
+
|
58
|
+
def header_perfix(file, keys)
|
59
|
+
perfix = "#{file.dirname}/"
|
60
|
+
suffix = file.basename.to_s
|
61
|
+
keys.inject([]) do |sum, name|
|
62
|
+
sum << [name.to_s, perfix, suffix]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def header_to_hash(keys, headers, index, buckets)
|
67
|
+
index = index.length
|
68
|
+
keys.inject('') do |sum, bucket|
|
69
|
+
buckte = HMapBucketStr.new(*bucket)
|
70
|
+
string_t = buckte.bucket_to_string(headers, index + sum.length)
|
71
|
+
buckets.push(buckte)
|
72
|
+
sum + string_t
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def merge_all_target_public_mapfile(targets, hmap_dir)
|
77
|
+
method = method(:from_header_mappings_by_file_accessor)
|
78
|
+
targets.each do |target|
|
79
|
+
hmap_file_name = "#{target.name}-All-Public-Headers.hmap"
|
80
|
+
single_target_mapfile(target.pod_targets, hmap_dir, hmap_file_name, method)
|
81
|
+
change_target_xcconfig_header_search_path([hmap_file_name], true, target)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def merge_all_pods_target_headers_mapfile(pod_targets, hmap_dir)
|
86
|
+
method = method(:from_header_mappings_by_file_accessor)
|
87
|
+
hmap_file_name = 'All-Pods-Headers.hmap'
|
88
|
+
single_target_mapfile(pod_targets, hmap_dir, hmap_file_name, method, :all_files)
|
89
|
+
change_target_xcconfig_header_search_path([hmap_file_name], false, *pod_targets)
|
90
|
+
end
|
91
|
+
|
92
|
+
def create_each_target_mapfile(pod_targets, hmap_dir)
|
93
|
+
pod_targets.each do |target|
|
94
|
+
HMMAP_TYPE.flat_map do |key, value|
|
95
|
+
hmap_file_name = "#{target.name}-#{value}-hmap.hmap"
|
96
|
+
method = method(:from_header_mappings_by_file_accessor)
|
97
|
+
single_target_mapfile([target], File.join(hmap_dir, target.name), hmap_file_name, method, key)
|
98
|
+
"#{target.name}/#{hmap_file_name}" if key == :all_files
|
99
|
+
end.compact
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def from_header_mappings_by_file_accessor(header_h, buckets, target, hmap_type)
|
104
|
+
hmap_t = hmap_type == :all_files ? 'headers' : "#{HMMAP_TYPE[hmap_type]}_headers"
|
105
|
+
valid_accessors = target.file_accessors.reject { |fa| fa.spec.non_library_specification? }
|
106
|
+
headers = valid_accessors.each_with_object({}) do |file_accessor, sum|
|
107
|
+
# Private headers will always end up in Pods/Headers/Private/PodA/*.h
|
108
|
+
# This will allow for `""` imports to work.
|
109
|
+
type_header = file_accessor.method(hmap_t.to_sym).call
|
110
|
+
Helper::PodHelper.header_mappings(file_accessor, type_header, target).each do |key, value|
|
111
|
+
sum[key] ||= []
|
112
|
+
sum[key] += value
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
if target.build_as_framework?
|
117
|
+
headers[target.prefix_header_path] = [target.prefix_header_path.basename]
|
118
|
+
headers[target.umbrella_header_path] = [target.umbrella_header_path.basename]
|
119
|
+
end
|
120
|
+
headers.each_with_object(buckets) do |header_f, sum|
|
121
|
+
keys = header_perfix(*header_f)
|
122
|
+
sum[0] += header_to_hash(keys, header_h, *sum)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def single_target_mapfile(pod_targets, hmap_dir, hmap_file_name, headers, hmap_type = :public_header_files)
|
127
|
+
hmap_file_path = Pathname(File.join(hmap_dir, hmap_file_name))
|
128
|
+
header_h = {}
|
129
|
+
buckets = pod_targets.inject(["\0", []]) do |bucktes, target|
|
130
|
+
headers.call(header_h, bucktes, target, hmap_type)
|
131
|
+
end
|
132
|
+
wirte_mapfile_to_path(hmap_file_path, buckets)
|
133
|
+
end
|
134
|
+
|
135
|
+
def wirte_mapfile_to_path(hmap_file_path, buckets)
|
136
|
+
print "\t - save hmap file to path:"
|
137
|
+
puts hmap_file_path.to_s.yellow
|
138
|
+
HMapFile.new(*buckets).write(hmap_file_path)
|
139
|
+
end
|
140
|
+
|
141
|
+
def change_target_xcconfig_header_search_path(hmap_h, use_headermap, *targets)
|
142
|
+
Utils.target_xcconfig_path(targets) do |xc|
|
143
|
+
Utils.change_xcconfig_header_search_path(xc, hmap_h, use_headermap: use_headermap,
|
144
|
+
save_origin: @save_origin_header_search_paths)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
|
2
|
+
require 'cocoapods'
|
3
|
+
|
4
|
+
module HMap
|
5
|
+
# A collection of Helper functions used throughout cocoapods-hmap-prebuilt.
|
6
|
+
module Helper
|
7
|
+
# A collection of PodHelper functions used throughout cocoapods-hmap-prebuilt.
|
8
|
+
module PodHelper
|
9
|
+
HEADER_EXTENSIONS = Pod::Sandbox::FileAccessor::HEADER_EXTENSIONS
|
10
|
+
|
11
|
+
def self.pod_analyze(config)
|
12
|
+
podfile = Pod::Podfile.from_file(config.podfile_path)
|
13
|
+
lockfile = Pod::Lockfile.from_file(config.lockfile_path)
|
14
|
+
Pod::Installer::Analyzer.new(config.sandbox, podfile, lockfile).analyze
|
15
|
+
end
|
16
|
+
|
17
|
+
# @!group Private helpers
|
18
|
+
|
19
|
+
# Returns the list of the paths founds in the file system for the
|
20
|
+
# attribute with given name. It takes into account any dir pattern and
|
21
|
+
# any file excluded in the specification.
|
22
|
+
#
|
23
|
+
# @param [Symbol] attribute
|
24
|
+
# the name of the attribute.
|
25
|
+
#
|
26
|
+
# @return [Array<Pathname>] the paths.
|
27
|
+
#
|
28
|
+
def self.paths_for_attribute(key, attribute, include_dirs: false)
|
29
|
+
file_patterns = key.spec_consumer.send(attribute)
|
30
|
+
options = {
|
31
|
+
exclude_patterns: key.spec_consumer.exclude_files,
|
32
|
+
dir_pattern: Pod::Sandbox::FileAccessor::GLOB_PATTERNS[attribute],
|
33
|
+
include_dirs: include_dirs
|
34
|
+
}
|
35
|
+
extensions = HEADER_EXTENSIONS
|
36
|
+
key.path_list.relative_glob(file_patterns, options).map do |f|
|
37
|
+
[f, key.path_list.root.join(f)] if extensions.include?(f.extname)
|
38
|
+
end.compact
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.header_mappings(file_accessor, headers, target)
|
42
|
+
consumer = file_accessor.spec_consumer
|
43
|
+
header_mappings_dir = consumer.header_mappings_dir
|
44
|
+
dir = target.headers_sandbox
|
45
|
+
dir_h = Pathname.new(target.product_module_name)
|
46
|
+
dir += consumer.header_dir if consumer.header_dir
|
47
|
+
mappings = {}
|
48
|
+
headers.each do |header|
|
49
|
+
next if header.to_s.include?('.framework/')
|
50
|
+
|
51
|
+
sub_dir = [dir, dir_h]
|
52
|
+
if header_mappings_dir
|
53
|
+
relative_path = header.relative_path_from(file_accessor.path_list.root + header_mappings_dir)
|
54
|
+
sub_dir << dir + relative_path.dirname
|
55
|
+
sub_dir << dir_h + relative_path.dirname
|
56
|
+
else
|
57
|
+
relative_path = header.relative_path_from(file_accessor.path_list.root)
|
58
|
+
sub_dir << relative_path.dirname
|
59
|
+
end
|
60
|
+
mappings[header] ||= []
|
61
|
+
sub_dir.uniq.each do |d|
|
62
|
+
mappings[header] << d + header.basename
|
63
|
+
end
|
64
|
+
mappings[header] << header.basename
|
65
|
+
end
|
66
|
+
mappings
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.pod_target_source_header(target, hmap_t)
|
70
|
+
target.header_mappings_by_file_accessor.keys.flat_map do |key|
|
71
|
+
paths_for_attribute(key, hmap_t)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.pod_target_source_header_map(target, hmap_t)
|
76
|
+
pod_target_source_header(target, hmap_t).each_with_object({}) do |f, sum|
|
77
|
+
file = f[1]
|
78
|
+
key = f[0].to_s
|
79
|
+
r_key = file.basename.to_s
|
80
|
+
sum[r_key] = [key, r_key].uniq
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
|
2
|
+
module HMap
|
3
|
+
HEADER_CONST = {
|
4
|
+
HMAP_HEADER_MAGIC_NUMBER: 0x686d6170,
|
5
|
+
HMAP_HEADER_VERSION: 0x0001,
|
6
|
+
HMAP_EMPTY_BUCKT_KEY: 0,
|
7
|
+
HMAP_SWAPPED_MAGIC: 0x70616d68,
|
8
|
+
HMAP_SWAPPED_VERSION: 0x0100
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
# A general purpose pseudo-structure.
|
12
|
+
# @abstract
|
13
|
+
class HMapStructure
|
14
|
+
# The String#unpack format of the data structure.
|
15
|
+
# @return [String] the unpacking format
|
16
|
+
# @api private
|
17
|
+
FORMAT = ''
|
18
|
+
|
19
|
+
# The size of the data structure, in bytes.
|
20
|
+
# @return [Integer] the size, in bytes
|
21
|
+
# @api private
|
22
|
+
SIZEOF = 0
|
23
|
+
|
24
|
+
SWAPPED = true
|
25
|
+
|
26
|
+
# @return [Integer] the size, in bytes, of the represented structure.
|
27
|
+
def self.bytesize
|
28
|
+
self::SIZEOF
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.format
|
32
|
+
self::FORMAT
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.swapped?
|
36
|
+
self::SWAPPED
|
37
|
+
end
|
38
|
+
|
39
|
+
# @param swapped [Bool] the swapped of the mapfile
|
40
|
+
# @param bin [String] the string to be unpacked into the new structure
|
41
|
+
# @return [HMap::HMapStructure] the resulting structure
|
42
|
+
# @api private
|
43
|
+
def self.new_from_bin(swapped, bin)
|
44
|
+
format = Utils.specialize_format(self::FORMAT, swapped)
|
45
|
+
new(*bin.unpack(format))
|
46
|
+
end
|
47
|
+
|
48
|
+
def serialize
|
49
|
+
[].pack(format)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Hash] a hash representation of this {HMapStructure}.
|
53
|
+
def to_h
|
54
|
+
{
|
55
|
+
'structure' => {
|
56
|
+
'format' => self.class::FORMAT,
|
57
|
+
'bytesize' => self.class.bytesize
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# HMapHeader structure.
|
64
|
+
# @see https://clang.llvm.org/doxygen/structclang_1_1HMapHeader.html
|
65
|
+
# @abstract
|
66
|
+
class HMapHeader < HMapStructure
|
67
|
+
# @return [HMap::HMapView, nil] the raw view associated with the load command,
|
68
|
+
# or nil if the HMapHeader was created via {create}.
|
69
|
+
attr_reader :num_entries, :magic, :version, :reserved, :strings_offset, :num_buckets, :max_value_length
|
70
|
+
|
71
|
+
FORMAT = 'L=1S=2L4'
|
72
|
+
# @see HMapStructure::SIZEOF
|
73
|
+
# @api private
|
74
|
+
SIZEOF = 24
|
75
|
+
|
76
|
+
# @api private
|
77
|
+
def initialize(magic, version, reserved, strings_offset, num_entries, num_buckets, max_value_length)
|
78
|
+
@magic = magic
|
79
|
+
@version = version
|
80
|
+
@reserved = reserved
|
81
|
+
@strings_offset = strings_offset
|
82
|
+
@num_entries = num_entries
|
83
|
+
@num_buckets = num_buckets
|
84
|
+
@max_value_length = max_value_length
|
85
|
+
super()
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [String] the serialized fields of the mafile
|
89
|
+
def serialize
|
90
|
+
format = Utils.specialize_format(FORMAT, SWAPPED)
|
91
|
+
[magic, version, reserved, strings_offset, num_entries, num_buckets, max_value_length].pack(format)
|
92
|
+
end
|
93
|
+
|
94
|
+
def description
|
95
|
+
<<-DESC
|
96
|
+
Hash bucket count: #{@num_buckets}
|
97
|
+
String table entry count: #{@num_entries}
|
98
|
+
Max value length: #{@max_value_length}
|
99
|
+
DESC
|
100
|
+
end
|
101
|
+
|
102
|
+
def to_h
|
103
|
+
{
|
104
|
+
'magic' => magic,
|
105
|
+
'version' => version,
|
106
|
+
'reserved' => reserved,
|
107
|
+
'strings_offset' => strings_offset,
|
108
|
+
'num_entries' => num_entries,
|
109
|
+
'num_buckets' => num_buckets,
|
110
|
+
'max_value_length' => max_value_length
|
111
|
+
}.merge super
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# HMapBucketStr => HMapBucket.
|
116
|
+
# @see https://clang.llvm.org/doxygen/structclang_1_1HMapHeader.html
|
117
|
+
# @abstract
|
118
|
+
class HMapBucketStr
|
119
|
+
attr_reader :uuid, :key, :perfix, :suffix
|
120
|
+
|
121
|
+
def initialize(key, perfix, suffix)
|
122
|
+
@uuid = Utils.string_downcase_hash(key)
|
123
|
+
@key = key
|
124
|
+
@perfix = perfix
|
125
|
+
@suffix = suffix
|
126
|
+
@str_ins = {}
|
127
|
+
end
|
128
|
+
|
129
|
+
def bucket_to_string(headers, index)
|
130
|
+
bucket = [key, perfix, suffix]
|
131
|
+
bucket.inject('') do |sum, arg|
|
132
|
+
if headers[arg].nil?
|
133
|
+
headers[arg] = sum.length + index
|
134
|
+
sum += "#{Utils.safe_encode(arg, 'ASCII-8BIT')}\0"
|
135
|
+
end
|
136
|
+
@str_ins[arg] = headers[arg]
|
137
|
+
sum
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def bucket
|
142
|
+
HMapBucket.new(@str_ins[@key], @str_ins[@perfix], @str_ins[@suffix])
|
143
|
+
end
|
144
|
+
|
145
|
+
# @return [String] the serialized fields of the mafile
|
146
|
+
def serialize
|
147
|
+
bucket.serialize
|
148
|
+
end
|
149
|
+
|
150
|
+
def description
|
151
|
+
<<-DESC
|
152
|
+
Key #{@key} -> Prefix #{@perfix}, Suffix #{@suffix}
|
153
|
+
DESC
|
154
|
+
end
|
155
|
+
|
156
|
+
def to_h
|
157
|
+
{
|
158
|
+
'key' => { 'index' => str_ins[@key], 'key' => @key },
|
159
|
+
'perfix' => { 'index' => str_ins[@perfix], 'perfix' => @perfix },
|
160
|
+
'suffix' => { 'index' => str_ins[@suffix], 'suffix' => @suffix }
|
161
|
+
}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# HMapBucket structure.
|
166
|
+
# @see https://clang.llvm.org/doxygen/structclang_1_1HMapHeader.html
|
167
|
+
# @abstract
|
168
|
+
class HMapBucket < HMapStructure
|
169
|
+
attr_accessor :key, :perfix, :suffix
|
170
|
+
|
171
|
+
SIZEOF = 12
|
172
|
+
|
173
|
+
FORMAT = 'L=3'
|
174
|
+
|
175
|
+
def initialize(key, perfix, suffix)
|
176
|
+
@key = key
|
177
|
+
@perfix = perfix
|
178
|
+
@suffix = suffix
|
179
|
+
super()
|
180
|
+
end
|
181
|
+
|
182
|
+
# @return [String] the serialized fields of the mafile
|
183
|
+
def serialize
|
184
|
+
format = Utils.specialize_format(FORMAT, SWAPPED)
|
185
|
+
[key, perfix, suffix].pack(format)
|
186
|
+
end
|
187
|
+
|
188
|
+
def to_a
|
189
|
+
[key, perfix, suffix]
|
190
|
+
end
|
191
|
+
|
192
|
+
def to_h
|
193
|
+
{
|
194
|
+
'key' => key,
|
195
|
+
'perfix' => perfix,
|
196
|
+
'suffix' => suffix
|
197
|
+
}.merge super
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# HMap blobs.
|
202
|
+
class HMapData
|
203
|
+
def initialize(buckets)
|
204
|
+
super()
|
205
|
+
count = buckets.count
|
206
|
+
nums = num_buckets(count, Utils.next_power_of_two(count))
|
207
|
+
entries = entries(count, nums)
|
208
|
+
@header = populate_hmap_header(nums, entries)
|
209
|
+
@buckets = add_bucket(buckets, nums)
|
210
|
+
end
|
211
|
+
|
212
|
+
def num_buckets(count, pow2)
|
213
|
+
if count < 8
|
214
|
+
pow2 <<= 1 if count * 4 >= pow2 * 3
|
215
|
+
pow2 < 8 ? 8 : pow2
|
216
|
+
else
|
217
|
+
index = count > 341 ? 2 : -3
|
218
|
+
padding = count / 85 % 7 + index
|
219
|
+
Utils.next_power_of_two(count * 3 + padding)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def entries(count, nums)
|
224
|
+
return count if nums == 8
|
225
|
+
|
226
|
+
last_pow = nums >> 1
|
227
|
+
index = last_pow < 1024 ? 3 : -2
|
228
|
+
count - (last_pow + 1 + index) / 3 + 1 + last_pow
|
229
|
+
end
|
230
|
+
|
231
|
+
# @return [String] the serialized fields of the mafile
|
232
|
+
def serialize
|
233
|
+
@header.serialize + @buckets.inject('') do |sum, bucket|
|
234
|
+
sum += if bucket.nil?
|
235
|
+
empty_b = [HEADER_CONST[:HMAP_EMPTY_BUCKT_KEY]]*3
|
236
|
+
empty_b.pack('L<3')
|
237
|
+
else
|
238
|
+
bucket
|
239
|
+
end
|
240
|
+
sum
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def add_bucket(buckets, num)
|
245
|
+
buckets.each_with_object(Array.new(num)) do |bucket, sum|
|
246
|
+
serialize = bucket.serialize
|
247
|
+
i = Utils.index_of_range(bucket.uuid, num)
|
248
|
+
loop do
|
249
|
+
sum[i] = serialize if sum[i].nil?
|
250
|
+
break if serialize == sum[i]
|
251
|
+
|
252
|
+
i = Utils.index_of_range(i += 1, num)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def populate_hmap_header(num_buckets, entries)
|
258
|
+
strings_offset = HMapHeader.bytesize + HMapBucket.bytesize * num_buckets
|
259
|
+
HMapHeader.new(HEADER_CONST[:HMAP_HEADER_MAGIC_NUMBER],
|
260
|
+
HEADER_CONST[:HMAP_HEADER_VERSION], 0, strings_offset, entries, num_buckets, 0)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'cocoapods'
|
2
|
+
|
3
|
+
module HMap
|
4
|
+
# A collection of utility functions used throughout cocoapods-hmap-prebuilt.
|
5
|
+
module Utils
|
6
|
+
HEADER_EXTENSIONS = Pod::Sandbox::FileAccessor::HEADER_EXTENSIONS
|
7
|
+
|
8
|
+
def self.index_of_range(num, range)
|
9
|
+
num &= range - 1
|
10
|
+
num
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.power_of_two?(num)
|
14
|
+
num != 0 && (num & (num - 1)).zero?
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.next_power_of_two(num)
|
18
|
+
num |= (num >> 1)
|
19
|
+
num |= (num >> 2)
|
20
|
+
num |= (num >> 4)
|
21
|
+
num |= (num >> 8)
|
22
|
+
num |= (num >> 16)
|
23
|
+
num |= (num >> 32)
|
24
|
+
num + 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.hash_set_value(hash, *args)
|
28
|
+
args.each do |arg|
|
29
|
+
hash.merge(arg)
|
30
|
+
end
|
31
|
+
hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.specialize_format(format, swapped)
|
35
|
+
modifier = swapped ? '<' : '>'
|
36
|
+
format.tr('=', modifier)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.string_downcase_hash(str)
|
40
|
+
str.downcase.bytes.inject(0) do |sum, value|
|
41
|
+
sum += value * 13
|
42
|
+
sum
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.update_changed_file(path, contents)
|
47
|
+
if path.exist?
|
48
|
+
content_stream = StringIO.new(contents)
|
49
|
+
identical = File.open(path, 'rb') { |f| FileUtils.compare_stream(f, content_stream) }
|
50
|
+
return if identical
|
51
|
+
end
|
52
|
+
path.dirname.mkpath
|
53
|
+
File.open(path, 'w') { |f| f.write(contents) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.swapped_magic?(magic, version)
|
57
|
+
magic.eql?(HEADER_CONST[:HMAP_SWAPPED_MAGIC]) && version.eql?(HEADER_CONST[:HMAP_SWAPPED_VERSION])
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.magic?(magic)
|
61
|
+
magic.eql?(HEADER_CONST[:HMAP_SWAPPED_MAGIC]) || magic.eql?(HEADER_CONST[:HMAP_HEADER_MAGIC_NUMBER])
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.safe_encode(string, target_encoding)
|
65
|
+
string.encode(target_encoding)
|
66
|
+
rescue Encoding::InvalidByteSequenceError
|
67
|
+
string.force_encoding(target_encoding)
|
68
|
+
rescue Encoding::UndefinedConversionError
|
69
|
+
string.encode(target_encoding, fallback: lambda { |c|
|
70
|
+
c.force_encoding(target_encoding)
|
71
|
+
})
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.clean_target_build_setting(targets, build_setting)
|
75
|
+
target_xcconfig_path(targets) do |xc|
|
76
|
+
clean_build_setting_to_xcconfig(xc, build_setting)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.target_xcconfig_path(targets)
|
81
|
+
targets.each do |target|
|
82
|
+
raise ClassIncludedError.new(target.class, Pod::Target) unless target.is_a?(Pod::Target)
|
83
|
+
|
84
|
+
config_h = Pod::Target.instance_method(:build_settings).bind(target).call
|
85
|
+
config_h.each_key do |configuration_name|
|
86
|
+
xcconfig = target.xcconfig_path(configuration_name)
|
87
|
+
yield(xcconfig) if block_given?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.change_xcconfig_header_search_path(xcconfig, hmap_h, use_headermap: true, save_origin: true)
|
93
|
+
hmap_header_serach_paths = hmap_h.inject('') do |sum, hmap_n|
|
94
|
+
hmap_pod_root_path = "${PODS_ROOT}/Headers/#{HMAP_DIR_NAME}/#{hmap_n}"
|
95
|
+
sum + "\"#{hmap_pod_root_path}\" "
|
96
|
+
end
|
97
|
+
save_build_setting_to_xcconfig(xcconfig, hmap_header_serach_paths, HEAD_SEARCH_PATHS, save_origin: save_origin) do |xc|
|
98
|
+
xc.attributes['USE_HEADERMAP'] = 'NO' unless use_headermap
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.save_build_setting_to_xcconfig(path, value, build_setting, save_origin: true)
|
103
|
+
xc = Xcodeproj::Config.new(path)
|
104
|
+
save_origin_build_setting = "SAVE_#{build_setting}"
|
105
|
+
hmap_build_setting = "HMAP_PREBUILT_#{build_setting}"
|
106
|
+
origin_build_setting = xc.attributes[build_setting]
|
107
|
+
|
108
|
+
if !origin_build_setting.nil? && !origin_build_setting.include?(hmap_build_setting)
|
109
|
+
xc.attributes[save_origin_build_setting] =
|
110
|
+
origin_build_setting
|
111
|
+
end
|
112
|
+
|
113
|
+
save_origin_build_setting_value = xc.attributes[save_origin_build_setting]
|
114
|
+
value = "#{value} ${#{save_origin_build_setting}}" if save_origin && !save_origin_build_setting_value.nil?
|
115
|
+
xc.attributes[hmap_build_setting] = value
|
116
|
+
xc.attributes[build_setting] = "${#{hmap_build_setting}}"
|
117
|
+
yield(xc) if block_given?
|
118
|
+
xc.save_as(path)
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.clean_build_setting_to_xcconfig(path, build_setting)
|
122
|
+
xc = Xcodeproj::Config.new(path)
|
123
|
+
save_origin_build_setting = "SAVE_#{build_setting}"
|
124
|
+
hmap_build_setting = "HMAP_PREBUILT_#{build_setting}"
|
125
|
+
return if xc.attributes[hmap_build_setting].nil?
|
126
|
+
|
127
|
+
xc.attributes[build_setting] = xc.attributes[save_origin_build_setting]
|
128
|
+
xc.attributes.delete(save_origin_build_setting)
|
129
|
+
xc.attributes.delete(hmap_build_setting)
|
130
|
+
xc.attributes['USE_HEADERMAP'] = 'YES'
|
131
|
+
xc.attributes.delete(build_setting) if xc.attributes[build_setting].nil?
|
132
|
+
xc.save_as(path)
|
133
|
+
puts "\t -xcconfig path: #{path} clean finish."
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module HMap
|
3
|
+
# A representation of some unspecified hmap data.
|
4
|
+
class HMapView
|
5
|
+
# @return [String] the raw hmap data
|
6
|
+
attr_reader :raw_data
|
7
|
+
|
8
|
+
# @return [Symbol] the endianness of the data (`:big` or `:little`)
|
9
|
+
attr_reader :endianness
|
10
|
+
|
11
|
+
# @return [Integer] the offset of the relevant data (in {#raw_data})
|
12
|
+
attr_reader :offset
|
13
|
+
|
14
|
+
# Creates a new HMapView.
|
15
|
+
def initialize(raw_data, endianness, offset)
|
16
|
+
@raw_data = raw_data
|
17
|
+
@endianness = endianness
|
18
|
+
@offset = offset
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Hash] a hash representation of this {HMapView}.
|
22
|
+
def to_h
|
23
|
+
{
|
24
|
+
'endianness' => endianness,
|
25
|
+
'offset' => offset
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'cocoapods-hmap-prebuilt/command/hmap_writer'
|
2
|
+
require 'cocoapods-hmap-prebuilt/command/hmap_reader'
|
3
|
+
|
4
|
+
module CocoapodsHmapPrebuiltHook
|
5
|
+
Pod::HooksManager.register('cocoapods-hmap-prebuilt', :post_install) do
|
6
|
+
Command::HMapWriter.run(["--project-directory=#{Config.instance.installation_root}", "--nosave-origin-header-search-paths"])
|
7
|
+
end
|
8
|
+
Pod::HooksManager.register('cocoapods-hmap-prebuilt', :post_update) do
|
9
|
+
Command::HMapWriter.run(["--project-directory=#{Config.instance.installation_root}", "--nosave-origin-header-search-paths"])
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cocoapods-hmap-prebuilt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- EricLou
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-08-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: coveralls
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: cocoapods
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.6'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.6'
|
83
|
+
description: A short description of cocoapods-hmap-prebuilt.
|
84
|
+
email:
|
85
|
+
- 499304609@qq.com
|
86
|
+
executables:
|
87
|
+
- hmap-prebuilt-read
|
88
|
+
- hmap-prebuilt-write
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- LICENSE
|
93
|
+
- README.md
|
94
|
+
- bin/hmap-prebuilt-read
|
95
|
+
- bin/hmap-prebuilt-write
|
96
|
+
- lib/cocoapods-hmap-prebuilt.rb
|
97
|
+
- lib/cocoapods-hmap-prebuilt/command/hmap_reader.rb
|
98
|
+
- lib/cocoapods-hmap-prebuilt/command/hmap_writer.rb
|
99
|
+
- lib/cocoapods-hmap-prebuilt/hmap_exceptions.rb
|
100
|
+
- lib/cocoapods-hmap-prebuilt/hmap_file.rb
|
101
|
+
- lib/cocoapods-hmap-prebuilt/hmap_file_reader.rb
|
102
|
+
- lib/cocoapods-hmap-prebuilt/hmap_file_writer.rb
|
103
|
+
- lib/cocoapods-hmap-prebuilt/hmap_helper.rb
|
104
|
+
- lib/cocoapods-hmap-prebuilt/hmap_struct.rb
|
105
|
+
- lib/cocoapods-hmap-prebuilt/hmap_utils.rb
|
106
|
+
- lib/cocoapods-hmap-prebuilt/hmap_version.rb
|
107
|
+
- lib/cocoapods-hmap-prebuilt/hmap_view.rb
|
108
|
+
- lib/cocoapods_plugin.rb
|
109
|
+
homepage: http://gitlab.webuy.ai/iOS/cocoapod-hamp-prebuilt.git
|
110
|
+
licenses:
|
111
|
+
- MIT
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '2.5'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubygems_version: 3.0.3
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: A longer description of cocoapods-hmap-prebuilt.
|
132
|
+
test_files: []
|