cocoapods-mapfile 0.2.2 → 0.2.3
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 +4 -4
- data/README.md +65 -64
- data/lib/cocoapods_plugin.rb +16 -16
- data/lib/hmap/command/hmap_gen.rb +19 -27
- data/lib/hmap/command/hmap_reader.rb +5 -5
- data/lib/hmap/command/hmap_writer.rb +5 -3
- data/lib/hmap/command.rb +3 -1
- data/lib/hmap/constants.rb +198 -0
- data/lib/hmap/{executable.rb → helper/executable.rb} +5 -6
- data/lib/hmap/hmap/hmap_bucketstr.rb +20 -0
- data/lib/hmap/{hmap_reader.rb → hmap/hmap_reader.rb} +4 -20
- data/lib/hmap/{hmap_saver.rb → hmap/hmap_saver.rb} +11 -6
- data/lib/hmap/{hmap_struct.rb → hmap/hmap_struct.rb} +0 -0
- data/lib/hmap/hmap/hmap_writer.rb +52 -0
- data/lib/hmap/{mapfile.rb → hmap/mapfile.rb} +1 -1
- data/lib/hmap/user_interface.rb +22 -0
- data/lib/hmap/version.rb +1 -1
- data/lib/hmap/xc/context.rb +23 -0
- data/lib/hmap/xc/header_entry.rb +55 -0
- data/lib/hmap/xc/header_type.rb +32 -0
- data/lib/hmap/xc/pbx_helper.rb +68 -0
- data/lib/hmap/xc/product_helper.rb +36 -0
- data/lib/hmap/xc/resolver.rb +129 -0
- data/lib/hmap/xc/target/build_setting.rb +126 -0
- data/lib/hmap/xc/target/target.rb +76 -0
- data/lib/hmap/xc/target/target_context.rb +29 -0
- data/lib/hmap/xc/target/target_helper.rb +114 -0
- data/lib/hmap/xc/target/target_vfs.rb +122 -0
- data/lib/hmap/xc/target/xcconfig_helper.rb +109 -0
- data/lib/hmap/xc/workspace/project.rb +120 -0
- data/lib/hmap/xc/workspace/project_helper.rb +92 -0
- data/lib/hmap/xc/workspace/workspace.rb +83 -0
- data/lib/hmap.rb +16 -14
- metadata +58 -20
- data/lib/hmap/framework/framework_vfs.rb +0 -94
- data/lib/hmap/helper/build_setting_constants.rb +0 -13
- data/lib/hmap/helper/hmap_helper.rb +0 -212
- data/lib/hmap/helper/pods_helper.rb +0 -98
- data/lib/hmap/helper/xcconfig_helper.rb +0 -105
- data/lib/hmap/hmap_writer.rb +0 -99
- data/lib/hmap/pods_specification.rb +0 -65
@@ -1,23 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'hmap/hmap/hmap_struct'
|
2
3
|
|
3
4
|
module HMap
|
4
|
-
# hmap bucket
|
5
|
-
class HMapBucketStr
|
6
|
-
attr_reader :key, :perfix, :suffix
|
7
|
-
|
8
|
-
def initialize(key, perfix, suffix)
|
9
|
-
@key = key
|
10
|
-
@perfix = perfix
|
11
|
-
@suffix = suffix
|
12
|
-
end
|
13
|
-
|
14
|
-
def description
|
15
|
-
<<-DESC
|
16
|
-
Key #{@key} -> Prefix #{@perfix}, Suffix #{@suffix}
|
17
|
-
DESC
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
5
|
# hmap file reader
|
22
6
|
class MapFileReader
|
23
7
|
# @return [String, nil] the filename loaded from, or nil if loaded from a binary
|
@@ -32,7 +16,7 @@ module HMap
|
|
32
16
|
# @return [HMap::HMapHeader]
|
33
17
|
attr_reader :header
|
34
18
|
|
35
|
-
# @return [Hash<HMap::HMapBucket => HMap::
|
19
|
+
# @return [Hash<HMap::HMapBucket => HMap::BucketStr>] an array of the file's bucktes
|
36
20
|
# @note bucktes are provided in order of ascending offset.
|
37
21
|
attr_reader :bucktes
|
38
22
|
|
@@ -55,7 +39,7 @@ module HMap
|
|
55
39
|
bucket_s = bucket.to_a.map do |key|
|
56
40
|
string_t[key..-1].match(/[^\0]+/)[0]
|
57
41
|
end
|
58
|
-
|
42
|
+
BucketStr.new(*bucket_s)
|
59
43
|
end
|
60
44
|
end
|
61
45
|
|
@@ -102,7 +86,7 @@ module HMap
|
|
102
86
|
|
103
87
|
# description
|
104
88
|
def description
|
105
|
-
sum = " Header map: #{filename}\n" + header.description
|
89
|
+
sum = " Header map path: #{filename}\n" + header.description
|
106
90
|
bucktes.each_with_index do |buckte_h, index|
|
107
91
|
sum += "\t- Bucket: #{index}" + Utils.safe_encode(buckte_h.values[0].description, 'UTF-8') unless buckte_h.nil?
|
108
92
|
sum
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'hmap/hmap/hmap_struct'
|
4
|
+
require 'hmap/hmap/mapfile'
|
5
|
+
|
3
6
|
module HMap
|
4
7
|
class HMapSaver
|
5
8
|
attr_reader :string_table, :buckets, :headers
|
@@ -19,7 +22,7 @@ module HMap
|
|
19
22
|
def header_to_hash(keys, headers, index, buckets)
|
20
23
|
index = index.length
|
21
24
|
keys.inject('') do |sum, bucket|
|
22
|
-
buckte =
|
25
|
+
buckte = BucketStr.new(*bucket)
|
23
26
|
string_t = buckte.bucket_to_string(headers, index + sum.length)
|
24
27
|
buckets.push(buckte)
|
25
28
|
sum + string_t
|
@@ -38,10 +41,12 @@ module HMap
|
|
38
41
|
headers[key]
|
39
42
|
end
|
40
43
|
|
41
|
-
def add_to_bucket(
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
def add_to_bucket(buckte)
|
45
|
+
key = add_to_headers(buckte.key)
|
46
|
+
perfix = add_to_headers(buckte.perfix)
|
47
|
+
suffix = add_to_headers(buckte.suffix)
|
48
|
+
bucket = HMapBucket.new(key, perfix, suffix)
|
49
|
+
bucket.uuid = Utils.string_downcase_hash(buckte.key)
|
45
50
|
@buckets << bucket
|
46
51
|
end
|
47
52
|
|
@@ -50,7 +55,7 @@ module HMap
|
|
50
55
|
end
|
51
56
|
|
52
57
|
def write_to(path)
|
53
|
-
MapFile.new(@string_table, @buckets).write(path)
|
58
|
+
MapFile.new(@string_table, @buckets).write(Pathname(path))
|
54
59
|
end
|
55
60
|
end
|
56
61
|
end
|
File without changes
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hmap/xc/workspace/workspace'
|
4
|
+
|
5
|
+
module HMap
|
6
|
+
class HMapTarget
|
7
|
+
attr_reader :name, :target
|
8
|
+
end
|
9
|
+
|
10
|
+
# Helper module which returns handle method from MapFileWriter.
|
11
|
+
class MapFileWriter
|
12
|
+
# @param save_origin_header_search_paths save_origin_header_search_paths
|
13
|
+
# @param clean_hmap clean up all hmap setup
|
14
|
+
# @param allow_targets this targets will save origin build setting
|
15
|
+
# @param use_build_in_headermap option use Xcode header map
|
16
|
+
def initialize(use_origin, project_root, clean_hmap)
|
17
|
+
UserInterface.puts("[hmapfile] Workspace/project root: #{project_root}..............")
|
18
|
+
UserInterface.puts("[hmapfile] Analyzing dependencies..............")
|
19
|
+
Resolver.instance.installation_root = project_root
|
20
|
+
Resolver.instance.use_origin = use_origin
|
21
|
+
create_hmapfile(clean_hmap)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Integrates the projects mapfile associated
|
25
|
+
# with the App project and Pods project.
|
26
|
+
#
|
27
|
+
# @param [clean] clean hmap dir @see #podfile
|
28
|
+
# @return [void]
|
29
|
+
#
|
30
|
+
def create_hmapfile(clean)
|
31
|
+
# {a,b}– Match pattern a or b.
|
32
|
+
# Though this looks like a regular expression quantifier, it isn't.
|
33
|
+
# For example, in regular expression, the pattern a{1,2} will match 1 or 2 'a' characters.
|
34
|
+
# In globbing, it will match the string a1 or a2.
|
35
|
+
paths = Dir.glob(File.join(Resolver.instance.installation_root, '*.{xcworkspace,xcodeproj}'))
|
36
|
+
workspace_paths = paths.select { |f| File.extname(f) == '.xcworkspace' }
|
37
|
+
xcs = if workspace_paths.nil?
|
38
|
+
project_paths = paths.select { |f| File.extname(f) == '.xcodeproj' }
|
39
|
+
Workspace.new_from_xcprojects(project_paths) unless project_paths.nil?
|
40
|
+
else
|
41
|
+
Workspace.new_from_xcworkspaces(workspace_paths)
|
42
|
+
end
|
43
|
+
xcs.each do |xc|
|
44
|
+
if clean
|
45
|
+
xc.remove_hmap_settings!
|
46
|
+
else
|
47
|
+
xc.write_save!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -6,7 +6,7 @@ module HMap
|
|
6
6
|
# @return mapfile string_table
|
7
7
|
attr_reader :string_table
|
8
8
|
|
9
|
-
# @return [Array<HMap::
|
9
|
+
# @return [Array<HMap::BucketStr>] an array of the file's bucktes
|
10
10
|
# @note bucktes are provided in order of ascending offset.
|
11
11
|
attr_reader :buckets
|
12
12
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module HMap
|
2
|
+
# Manages the UI output so clients can customize it.
|
3
|
+
#
|
4
|
+
module UserInterface
|
5
|
+
# Prints a message to standard output.
|
6
|
+
#
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
def self.puts(message)
|
10
|
+
STDOUT.puts message
|
11
|
+
end
|
12
|
+
|
13
|
+
# Prints a message to standard error.
|
14
|
+
#
|
15
|
+
# @return [void]
|
16
|
+
#
|
17
|
+
def self.warn(message)
|
18
|
+
STDERR.puts message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
UI = UserInterface
|
22
|
+
end
|
data/lib/hmap/version.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HMap
|
4
|
+
class Context
|
5
|
+
attr_reader :build_root, :hmap_root, :temp_name, :build_dir, :temp_dir
|
6
|
+
|
7
|
+
def initialize(build_root, temp_dir, hmap_root, temp_name, build_dir)
|
8
|
+
@build_root = build_root
|
9
|
+
@temp_dir = temp_dir
|
10
|
+
@hmap_root = hmap_root
|
11
|
+
@temp_name = temp_name
|
12
|
+
@build_dir = build_dir || ''
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_path(platform)
|
16
|
+
File.join(build_root, platform.to_s, build_dir)
|
17
|
+
end
|
18
|
+
|
19
|
+
def temp_path(platform)
|
20
|
+
File.join(temp_dir, platform.to_s, temp_name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module HMap
|
2
|
+
class HeaderEntry
|
3
|
+
attr_reader :path, :extra_keys, :type
|
4
|
+
|
5
|
+
def initialize(path, extra_keys, type)
|
6
|
+
@path = path
|
7
|
+
@extra_keys = extra_keys
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def project_buckets
|
12
|
+
h_name = File.basename(path)
|
13
|
+
h_dir = File.dirname(path)
|
14
|
+
[BucketStr.new(h_name, "#{h_dir}/", h_name)]
|
15
|
+
end
|
16
|
+
|
17
|
+
def module_buckets(moudle_name)
|
18
|
+
h_name = File.basename(path)
|
19
|
+
module_p = "#{moudle_name}/"
|
20
|
+
[BucketStr.new(h_name, module_p, h_name)]
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_module_buckets(moudle_name)
|
24
|
+
h_name = File.basename(path)
|
25
|
+
h_dir = File.dirname(path)
|
26
|
+
module_k = "#{moudle_name}/#{h_name}"
|
27
|
+
[BucketStr.new(module_k, "#{h_dir}/", h_name)]
|
28
|
+
end
|
29
|
+
|
30
|
+
def project_buckets_extra
|
31
|
+
h_name = File.basename(path)
|
32
|
+
h_dir = File.dirname(path)
|
33
|
+
buckets = []
|
34
|
+
buckets << BucketStr.new(h_name, "#{h_dir}/", h_name) unless extra_keys.include?(h_name)
|
35
|
+
buckets + extra_keys.map { |key| BucketStr.new(key, "#{h_dir}/", h_name) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def module_buckets_extra(moudle_name)
|
39
|
+
h_name = File.basename(path)
|
40
|
+
module_p = "#{moudle_name}/"
|
41
|
+
buckets = []
|
42
|
+
buckets << BucketStr.new(h_name, module_p, h_name) unless extra_keys.include?(h_name)
|
43
|
+
buckets + extra_keys.map { |key| BucketStr.new(key, module_p, h_name) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def full_module_buckets_extra(moudle_name)
|
47
|
+
h_name = File.basename(path)
|
48
|
+
h_dir = File.dirname(path)
|
49
|
+
module_k = "#{moudle_name}/#{h_name}"
|
50
|
+
buckets = []
|
51
|
+
buckets << BucketStr.new(module_k, "#{h_dir}/", h_name) unless extra_keys.include?(module_k)
|
52
|
+
buckets + extra_keys.map { |key| BucketStr.new(key, "#{h_dir}/", h_name) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
require 'hmap/xc/header_entry'
|
3
|
+
|
4
|
+
module HMap
|
5
|
+
module HeaderType
|
6
|
+
def public_entrys
|
7
|
+
return @public_entrys if defined?(@public_entrys)
|
8
|
+
|
9
|
+
@public_entrys = entrys.select { |entry| entry.type == :Public }
|
10
|
+
end
|
11
|
+
|
12
|
+
def private_entrys
|
13
|
+
return @private_entrys if defined?(@private_entrys)
|
14
|
+
|
15
|
+
@private_entrys = entrys.select { |entry| entry.type == :Private }
|
16
|
+
end
|
17
|
+
|
18
|
+
def project_entrys
|
19
|
+
return @project_entrys if defined?(@project_entrys)
|
20
|
+
|
21
|
+
@project_entrys = entrys.select { |entry| entry.type == :Project }
|
22
|
+
end
|
23
|
+
|
24
|
+
def use_vfs?
|
25
|
+
!public_entrys.empty? || !private_entrys.empty? || build_as_framework?
|
26
|
+
end
|
27
|
+
|
28
|
+
def headers_hash(*types)
|
29
|
+
Hash[types.map { |type| [type, send(type)] }]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module HMap
|
2
|
+
module PBXHelper
|
3
|
+
def self.get_groups(xct)
|
4
|
+
groups = xct.referrers.select { |e| e.is_a?(Constants::PBXGroup) } || []
|
5
|
+
groups += groups.flat_map { |g| get_groups(g) }
|
6
|
+
groups.compact.reverse
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.group_paths(xct)
|
10
|
+
ps = get_groups(xct).map do |g|
|
11
|
+
s_hash = g.instance_variable_get('@simple_attributes_hash')
|
12
|
+
s_hash['path'] unless s_hash.nil?
|
13
|
+
end.compact
|
14
|
+
File.join(*ps)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.uses_swift?(target)
|
18
|
+
source_files = target.build_phases.flat_map do |phase|
|
19
|
+
phase.files if phase.is_a?(Constants::PBXSourcesBuildPhase)
|
20
|
+
end.compact
|
21
|
+
source_files.any? do |file|
|
22
|
+
path = file.file_ref.instance_variable_get('@simple_attributes_hash')['path'] || ''
|
23
|
+
File.extname(path) == '.swift'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.build_as_framework?(target)
|
28
|
+
target.symbol_type == :framework if target.respond_to?(:symbol_type)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.defines_module?(target)
|
32
|
+
return true if build_as_framework?(target)
|
33
|
+
|
34
|
+
bus = target.build_configuration_list.build_configurations.map do |bu|
|
35
|
+
bu.instance_variable_get('@simple_attributes_hash')['buildSettings'] || {}
|
36
|
+
end
|
37
|
+
|
38
|
+
bus.any? { |s| s['DEFINES_MODULE'] == 'YES' }
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.projects(*p_paths)
|
42
|
+
return if p_paths.empty?
|
43
|
+
|
44
|
+
p_paths.flat_map do |pj|
|
45
|
+
project = Xcodeproj::Project.open(pj)
|
46
|
+
p_path = File.dirname(project.path)
|
47
|
+
project.root_object.project_references.map do |sp|
|
48
|
+
ff = sp[:project_ref]
|
49
|
+
path = ff.instance_variable_get('@simple_attributes_hash')['path'] || ''
|
50
|
+
full_path = File.join(p_path, path)
|
51
|
+
Xcodeproj::Project.open(full_path)
|
52
|
+
end << project
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.project_references(project)
|
57
|
+
return if project.nil?
|
58
|
+
|
59
|
+
p_path = File.dirname(project.path)
|
60
|
+
project.root_object.project_references.map do |sp|
|
61
|
+
ff = sp[:project_ref]
|
62
|
+
path = ff.instance_variable_get('@simple_attributes_hash')['path'] || ''
|
63
|
+
full_path = File.join(p_path, path)
|
64
|
+
Xcodeproj::Project.open(full_path)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'hmap/xc/resolver'
|
3
|
+
module HMap
|
4
|
+
class ProductPath
|
5
|
+
attr_reader :path, :build_setting, :name
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@path = path
|
9
|
+
raise ArgumentError, "#{path}: can not get build directory" if @build_setting.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_root
|
13
|
+
Pathname(build_setting[Constants::BUILD_DIR])
|
14
|
+
end
|
15
|
+
|
16
|
+
def obj_root
|
17
|
+
Pathname(build_setting[Constants::OBJROOT])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class WorkspaceProductPath < ProductPath
|
22
|
+
def initialize(path)
|
23
|
+
@name = File.basename(path, '.xcworkspace')
|
24
|
+
@build_setting = Resolver.instance.workspace_build_settings(path)
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ProjectProductPath < ProductPath
|
30
|
+
def initialize(path)
|
31
|
+
@name = File.basename(path, '.xcodeproj')
|
32
|
+
@build_setting = Resolver.instance.project_build_settings(path)
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hmap/helper/executable'
|
4
|
+
|
5
|
+
module HMap
|
6
|
+
class Resolver
|
7
|
+
# @return [Array<String>] The filenames that the Podfile can have ordered
|
8
|
+
# by priority.
|
9
|
+
#
|
10
|
+
PODFILE_NAMES = [
|
11
|
+
'CocoaPods.podfile.yaml',
|
12
|
+
'CocoaPods.podfile',
|
13
|
+
'Podfile',
|
14
|
+
'Podfile.rb'
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
attr_accessor :use_origin
|
18
|
+
|
19
|
+
def self.instance
|
20
|
+
@instance ||= new
|
21
|
+
end
|
22
|
+
|
23
|
+
# Sets the current config instance. If set to nil the config will be
|
24
|
+
# recreated when needed.
|
25
|
+
#
|
26
|
+
# @param [Config, Nil] the instance.
|
27
|
+
#
|
28
|
+
# @return [void]
|
29
|
+
#
|
30
|
+
class << self
|
31
|
+
attr_writer :instance
|
32
|
+
end
|
33
|
+
|
34
|
+
def workspace_build_settings(workspace)
|
35
|
+
workspace_dic = xcodebuild_list(workspace)['workspace']
|
36
|
+
schemes = workspace_dic['schemes'] || []
|
37
|
+
targets = xcodebuild_workspace(workspace, schemes[0]) || []
|
38
|
+
targets.first['buildSettings']
|
39
|
+
end
|
40
|
+
|
41
|
+
def project_build_settings(project_path)
|
42
|
+
targets = xcodebuild(project_path) || []
|
43
|
+
targets.first['buildSettings']
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Pathname] the root of the workspace or project where is located.
|
47
|
+
#
|
48
|
+
def installation_root
|
49
|
+
@installation_root ||= begin
|
50
|
+
current_dir = Pathname.new(Dir.pwd.unicode_normalize)
|
51
|
+
current_path = current_dir
|
52
|
+
until current_path.root?
|
53
|
+
if podfile_path_in_dir(current_path)
|
54
|
+
installation_root = current_path
|
55
|
+
puts("[in #{current_path}]") unless current_path == current_dir
|
56
|
+
break
|
57
|
+
else
|
58
|
+
current_path = current_path.parent
|
59
|
+
end
|
60
|
+
end
|
61
|
+
installation_root || current_dir
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
attr_writer :installation_root
|
66
|
+
alias project_root installation_root
|
67
|
+
|
68
|
+
def verbose?
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [String] Executes xcodebuild list in the current working directory and
|
73
|
+
# returns its output (both STDOUT and STDERR).
|
74
|
+
#
|
75
|
+
def xcodebuild_list(workspace)
|
76
|
+
command = %W[-workspace #{workspace}]
|
77
|
+
command += %w[-json -list]
|
78
|
+
results = Executable.execute_command('xcodebuild', command, false)
|
79
|
+
JSON.parse(results) unless results.nil?
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [hash] Executes xcodebuild -workspace -scheme in the current working directory and
|
83
|
+
# returns its output (both STDOUT and STDERR).
|
84
|
+
#
|
85
|
+
def xcodebuild_workspace(workspace, scheme)
|
86
|
+
command = %W[-workspace #{workspace}]
|
87
|
+
command += %W[-scheme #{scheme}]
|
88
|
+
xcodebuild(command)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [hash] Executes xcodebuild -project in the current working directory and
|
92
|
+
# returns its output (both STDOUT and STDERR).
|
93
|
+
#
|
94
|
+
def xcodebuild_project(project)
|
95
|
+
command = %W[-project #{project}]
|
96
|
+
xcodebuild(command)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Returns the path of the Podfile in the given dir if any exists.
|
102
|
+
#
|
103
|
+
# @param [Pathname] dir
|
104
|
+
# The directory where to look for the Podfile.
|
105
|
+
#
|
106
|
+
# @return [Pathname] The path of the Podfile.
|
107
|
+
# @return [Nil] If not Podfile was found in the given dir
|
108
|
+
#
|
109
|
+
def podfile_path_in_dir(dir)
|
110
|
+
PODFILE_NAMES.each do |filename|
|
111
|
+
candidate = dir + filename
|
112
|
+
return candidate if candidate.file?
|
113
|
+
end
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
|
117
|
+
# @return [hash] Executes xcodebuild in the current working directory, get build settings and
|
118
|
+
# returns its output as hash (both STDOUT and STDERR).
|
119
|
+
#
|
120
|
+
def xcodebuild(command)
|
121
|
+
command += %w[-json -showBuildSettings]
|
122
|
+
results = Executable.execute_command('xcodebuild', command, false)
|
123
|
+
index = results.index(/"action"/m)
|
124
|
+
reg = results[index..-1]
|
125
|
+
reg = "[\n{\n#{reg}"
|
126
|
+
JSON.parse(reg) unless results.nil?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'hmap/xc/target/target_vfs'
|
3
|
+
|
4
|
+
module HMap
|
5
|
+
class Platform
|
6
|
+
attr_reader :configuration, :platform
|
7
|
+
|
8
|
+
def self.new_from_platforms(configuration, platforms)
|
9
|
+
Utils.effective_platforms_names(platforms).map { |pl| new(configuration, pl) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(configuration, platform)
|
13
|
+
@configuration = configuration
|
14
|
+
@platform = platform
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"#{configuration}-#{platform}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module HMap
|
24
|
+
class BuildSettings
|
25
|
+
attr_reader :type, :platform
|
26
|
+
|
27
|
+
def self.new_from_platforms(type, platforms, context)
|
28
|
+
platforms.map { |platform| new(type, platform.to_s, context) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(type, platform, context)
|
32
|
+
@type = type
|
33
|
+
@platform = platform.to_s || ''
|
34
|
+
@context = context
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_or_symlink(path, data, need_platform)
|
38
|
+
return if data.nil? && path.nil?
|
39
|
+
|
40
|
+
if data.nil?
|
41
|
+
dir = platform if type == :all_product_headers
|
42
|
+
path = Constants.instance.full_hmap_filepath(type, path, dir)
|
43
|
+
symlink_to(path, need_platform)
|
44
|
+
else
|
45
|
+
write(data, need_platform)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def file_name
|
52
|
+
return @file_name if defined? @file_name
|
53
|
+
|
54
|
+
product_name = @context.product_name if @context.respond_to? :product_name
|
55
|
+
@file_name = Constants.instance.full_hmap_filename(type, product_name)
|
56
|
+
end
|
57
|
+
|
58
|
+
def hmap_filepath(need_platform)
|
59
|
+
platform = ''
|
60
|
+
platform = @platform if need_platform
|
61
|
+
hmap_root = File.join(@context.hmap_root, platform, @context.temp_name)
|
62
|
+
File.join(hmap_root, file_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
def symlink_to(path, need_platform)
|
66
|
+
return unless path.exist?
|
67
|
+
|
68
|
+
filepath = Pathname.new(hmap_filepath(need_platform))
|
69
|
+
filepath.dirname.mkpath unless filepath.exist?
|
70
|
+
return if File.identical?(filepath, path)
|
71
|
+
|
72
|
+
filepath.make_symlink(path)
|
73
|
+
end
|
74
|
+
|
75
|
+
def write(data, need_platform)
|
76
|
+
path = Constants.instance.full_hmap_filepath(type, hmap_filepath(need_platform))
|
77
|
+
if type == :all_product_headers
|
78
|
+
da = data[platform] || []
|
79
|
+
TargetVFSWriter.new(da).write!(path)
|
80
|
+
else
|
81
|
+
HMapSaver.new_from_buckets(data).write_to(path)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class BuildSettingsWriter
|
87
|
+
attr_reader :platforms
|
88
|
+
|
89
|
+
# Initialize a new instance
|
90
|
+
#
|
91
|
+
# @param [Array<HMap::Platform>] platforms
|
92
|
+
# the platforms to lint.
|
93
|
+
#
|
94
|
+
# @param [HMap::Context] context
|
95
|
+
# the Project or target information.
|
96
|
+
#
|
97
|
+
def initialize(platforms, context)
|
98
|
+
@platforms = platforms
|
99
|
+
@context = context
|
100
|
+
end
|
101
|
+
|
102
|
+
def write_or_symlink(path, data, platforms = [])
|
103
|
+
build_settings.each do |setting|
|
104
|
+
type_data = data[setting.type] unless data.nil?
|
105
|
+
next if type_data.nil? && path.nil?
|
106
|
+
|
107
|
+
need_platform = platforms.include?(setting.type)
|
108
|
+
setting.write_or_symlink(path, type_data, need_platform)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def build_settings
|
115
|
+
return @build_settings if defined? @build_settings
|
116
|
+
|
117
|
+
@build_settings = Constants::HMAP_FILE_TYPE.flat_map do |type|
|
118
|
+
if @platforms.empty?
|
119
|
+
BuildSettings.new(type, nil, @context)
|
120
|
+
else
|
121
|
+
BuildSettings.new_from_platforms(type, @platforms, @context)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|