cocoapods-mapfile 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|