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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +65 -64
  3. data/lib/cocoapods_plugin.rb +16 -16
  4. data/lib/hmap/command/hmap_gen.rb +19 -27
  5. data/lib/hmap/command/hmap_reader.rb +5 -5
  6. data/lib/hmap/command/hmap_writer.rb +5 -3
  7. data/lib/hmap/command.rb +3 -1
  8. data/lib/hmap/constants.rb +198 -0
  9. data/lib/hmap/{executable.rb → helper/executable.rb} +5 -6
  10. data/lib/hmap/hmap/hmap_bucketstr.rb +20 -0
  11. data/lib/hmap/{hmap_reader.rb → hmap/hmap_reader.rb} +4 -20
  12. data/lib/hmap/{hmap_saver.rb → hmap/hmap_saver.rb} +11 -6
  13. data/lib/hmap/{hmap_struct.rb → hmap/hmap_struct.rb} +0 -0
  14. data/lib/hmap/hmap/hmap_writer.rb +52 -0
  15. data/lib/hmap/{mapfile.rb → hmap/mapfile.rb} +1 -1
  16. data/lib/hmap/user_interface.rb +22 -0
  17. data/lib/hmap/version.rb +1 -1
  18. data/lib/hmap/xc/context.rb +23 -0
  19. data/lib/hmap/xc/header_entry.rb +55 -0
  20. data/lib/hmap/xc/header_type.rb +32 -0
  21. data/lib/hmap/xc/pbx_helper.rb +68 -0
  22. data/lib/hmap/xc/product_helper.rb +36 -0
  23. data/lib/hmap/xc/resolver.rb +129 -0
  24. data/lib/hmap/xc/target/build_setting.rb +126 -0
  25. data/lib/hmap/xc/target/target.rb +76 -0
  26. data/lib/hmap/xc/target/target_context.rb +29 -0
  27. data/lib/hmap/xc/target/target_helper.rb +114 -0
  28. data/lib/hmap/xc/target/target_vfs.rb +122 -0
  29. data/lib/hmap/xc/target/xcconfig_helper.rb +109 -0
  30. data/lib/hmap/xc/workspace/project.rb +120 -0
  31. data/lib/hmap/xc/workspace/project_helper.rb +92 -0
  32. data/lib/hmap/xc/workspace/workspace.rb +83 -0
  33. data/lib/hmap.rb +16 -14
  34. metadata +58 -20
  35. data/lib/hmap/framework/framework_vfs.rb +0 -94
  36. data/lib/hmap/helper/build_setting_constants.rb +0 -13
  37. data/lib/hmap/helper/hmap_helper.rb +0 -212
  38. data/lib/hmap/helper/pods_helper.rb +0 -98
  39. data/lib/hmap/helper/xcconfig_helper.rb +0 -105
  40. data/lib/hmap/hmap_writer.rb +0 -99
  41. 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::HMapBucketStr>] an array of the file's bucktes
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
- HMapBucketStr.new(*bucket_s)
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 = HMapBucketStr.new(*bucket)
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(buckets)
42
- values = buckets.map { |key| add_to_headers(key) }
43
- bucket = HMapBucket.new(*values)
44
- bucket.uuid = Utils.string_downcase_hash(buckets.first)
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::HMapBucketStr>] an array of the file's bucktes
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HMap
4
- VERSION = '0.2.2'
4
+ VERSION = '0.2.3'
5
5
  end
@@ -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