cocoapods-tt 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.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cocoapods-tt/command/native/install.rb +56 -0
  3. data/lib/cocoapods-tt/command/native/update.rb +157 -0
  4. data/lib/cocoapods-tt/command/tt/make.rb +92 -0
  5. data/lib/cocoapods-tt/command/tt.rb +115 -0
  6. data/lib/cocoapods-tt/command.rb +1 -0
  7. data/lib/cocoapods-tt/gem_version.rb +3 -0
  8. data/lib/cocoapods-tt/native/command.rb +185 -0
  9. data/lib/cocoapods-tt/native/config.rb +366 -0
  10. data/lib/cocoapods-tt/native/core_overrides.rb +1 -0
  11. data/lib/cocoapods-tt/native/downloader/cache.rb +322 -0
  12. data/lib/cocoapods-tt/native/downloader/request.rb +86 -0
  13. data/lib/cocoapods-tt/native/downloader/response.rb +16 -0
  14. data/lib/cocoapods-tt/native/downloader.rb +192 -0
  15. data/lib/cocoapods-tt/native/executable.rb +247 -0
  16. data/lib/cocoapods-tt/native/external_sources/abstract_external_source.rb +205 -0
  17. data/lib/cocoapods-tt/native/external_sources/downloader_source.rb +30 -0
  18. data/lib/cocoapods-tt/native/external_sources/path_source.rb +55 -0
  19. data/lib/cocoapods-tt/native/external_sources/podspec_source.rb +54 -0
  20. data/lib/cocoapods-tt/native/external_sources.rb +57 -0
  21. data/lib/cocoapods-tt/native/gem_version.rb +5 -0
  22. data/lib/cocoapods-tt/native/generator/acknowledgements/markdown.rb +44 -0
  23. data/lib/cocoapods-tt/native/generator/acknowledgements/plist.rb +94 -0
  24. data/lib/cocoapods-tt/native/generator/acknowledgements.rb +107 -0
  25. data/lib/cocoapods-tt/native/generator/app_target_helper.rb +363 -0
  26. data/lib/cocoapods-tt/native/generator/bridge_support.rb +22 -0
  27. data/lib/cocoapods-tt/native/generator/constant.rb +19 -0
  28. data/lib/cocoapods-tt/native/generator/copy_dsyms_script.rb +56 -0
  29. data/lib/cocoapods-tt/native/generator/copy_resources_script.rb +223 -0
  30. data/lib/cocoapods-tt/native/generator/copy_xcframework_script.rb +227 -0
  31. data/lib/cocoapods-tt/native/generator/dummy_source.rb +31 -0
  32. data/lib/cocoapods-tt/native/generator/embed_frameworks_script.rb +196 -0
  33. data/lib/cocoapods-tt/native/generator/file_list.rb +39 -0
  34. data/lib/cocoapods-tt/native/generator/header.rb +103 -0
  35. data/lib/cocoapods-tt/native/generator/info_plist_file.rb +128 -0
  36. data/lib/cocoapods-tt/native/generator/module_map.rb +99 -0
  37. data/lib/cocoapods-tt/native/generator/prefix_header.rb +60 -0
  38. data/lib/cocoapods-tt/native/generator/script_phase_constants.rb +100 -0
  39. data/lib/cocoapods-tt/native/generator/umbrella_header.rb +46 -0
  40. data/lib/cocoapods-tt/native/hooks_manager.rb +132 -0
  41. data/lib/cocoapods-tt/native/installer/analyzer/analysis_result.rb +87 -0
  42. data/lib/cocoapods-tt/native/installer/analyzer/locking_dependency_analyzer.rb +103 -0
  43. data/lib/cocoapods-tt/native/installer/analyzer/pod_variant.rb +87 -0
  44. data/lib/cocoapods-tt/native/installer/analyzer/pod_variant_set.rb +175 -0
  45. data/lib/cocoapods-tt/native/installer/analyzer/podfile_dependency_cache.rb +55 -0
  46. data/lib/cocoapods-tt/native/installer/analyzer/sandbox_analyzer.rb +268 -0
  47. data/lib/cocoapods-tt/native/installer/analyzer/specs_state.rb +108 -0
  48. data/lib/cocoapods-tt/native/installer/analyzer/target_inspection_result.rb +58 -0
  49. data/lib/cocoapods-tt/native/installer/analyzer/target_inspector.rb +258 -0
  50. data/lib/cocoapods-tt/native/installer/analyzer.rb +1204 -0
  51. data/lib/cocoapods-tt/native/installer/base_install_hooks_context.rb +135 -0
  52. data/lib/cocoapods-tt/native/installer/installation_options.rb +195 -0
  53. data/lib/cocoapods-tt/native/installer/pod_source_installer.rb +224 -0
  54. data/lib/cocoapods-tt/native/installer/pod_source_preparer.rb +77 -0
  55. data/lib/cocoapods-tt/native/installer/podfile_validator.rb +168 -0
  56. data/lib/cocoapods-tt/native/installer/post_install_hooks_context.rb +9 -0
  57. data/lib/cocoapods-tt/native/installer/post_integrate_hooks_context.rb +9 -0
  58. data/lib/cocoapods-tt/native/installer/pre_install_hooks_context.rb +51 -0
  59. data/lib/cocoapods-tt/native/installer/pre_integrate_hooks_context.rb +9 -0
  60. data/lib/cocoapods-tt/native/installer/project_cache/project_cache.rb +11 -0
  61. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analysis_result.rb +53 -0
  62. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analyzer.rb +200 -0
  63. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_version.rb +43 -0
  64. data/lib/cocoapods-tt/native/installer/project_cache/project_installation_cache.rb +103 -0
  65. data/lib/cocoapods-tt/native/installer/project_cache/project_metadata_cache.rb +73 -0
  66. data/lib/cocoapods-tt/native/installer/project_cache/target_cache_key.rb +176 -0
  67. data/lib/cocoapods-tt/native/installer/project_cache/target_metadata.rb +74 -0
  68. data/lib/cocoapods-tt/native/installer/sandbox_dir_cleaner.rb +105 -0
  69. data/lib/cocoapods-tt/native/installer/sandbox_header_paths_installer.rb +45 -0
  70. data/lib/cocoapods-tt/native/installer/source_provider_hooks_context.rb +34 -0
  71. data/lib/cocoapods-tt/native/installer/target_uuid_generator.rb +34 -0
  72. data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +179 -0
  73. data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator.rb +815 -0
  74. data/lib/cocoapods-tt/native/installer/user_project_integrator.rb +280 -0
  75. data/lib/cocoapods-tt/native/installer/xcode/multi_pods_project_generator.rb +82 -0
  76. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +66 -0
  77. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_installer.rb +192 -0
  78. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/app_host_installer.rb +154 -0
  79. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/file_references_installer.rb +329 -0
  80. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +195 -0
  81. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_installer.rb +1239 -0
  82. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_integrator.rb +312 -0
  83. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pods_project_writer.rb +90 -0
  84. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/project_generator.rb +120 -0
  85. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installation_result.rb +140 -0
  86. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer.rb +257 -0
  87. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer_helper.rb +110 -0
  88. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator.rb +291 -0
  89. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator_result.rb +54 -0
  90. data/lib/cocoapods-tt/native/installer/xcode/single_pods_project_generator.rb +38 -0
  91. data/lib/cocoapods-tt/native/installer/xcode/target_validator.rb +170 -0
  92. data/lib/cocoapods-tt/native/installer/xcode.rb +11 -0
  93. data/lib/cocoapods-tt/native/installer.rb +1044 -0
  94. data/lib/cocoapods-tt/native/native_target_extension.rb +60 -0
  95. data/lib/cocoapods-tt/native/open-uri.rb +33 -0
  96. data/lib/cocoapods-tt/native/podfile.rb +13 -0
  97. data/lib/cocoapods-tt/native/project.rb +544 -0
  98. data/lib/cocoapods-tt/native/resolver/lazy_specification.rb +88 -0
  99. data/lib/cocoapods-tt/native/resolver/resolver_specification.rb +41 -0
  100. data/lib/cocoapods-tt/native/resolver.rb +600 -0
  101. data/lib/cocoapods-tt/native/sandbox/file_accessor.rb +532 -0
  102. data/lib/cocoapods-tt/native/sandbox/headers_store.rb +163 -0
  103. data/lib/cocoapods-tt/native/sandbox/path_list.rb +242 -0
  104. data/lib/cocoapods-tt/native/sandbox/pod_dir_cleaner.rb +71 -0
  105. data/lib/cocoapods-tt/native/sandbox/podspec_finder.rb +23 -0
  106. data/lib/cocoapods-tt/native/sandbox.rb +470 -0
  107. data/lib/cocoapods-tt/native/sources_manager.rb +221 -0
  108. data/lib/cocoapods-tt/native/target/aggregate_target.rb +558 -0
  109. data/lib/cocoapods-tt/native/target/build_settings.rb +1385 -0
  110. data/lib/cocoapods-tt/native/target/pod_target.rb +1168 -0
  111. data/lib/cocoapods-tt/native/target.rb +378 -0
  112. data/lib/cocoapods-tt/native/user_interface/error_report.rb +204 -0
  113. data/lib/cocoapods-tt/native/user_interface/inspector_reporter.rb +102 -0
  114. data/lib/cocoapods-tt/native/user_interface.rb +463 -0
  115. data/lib/cocoapods-tt/native/validator.rb +1170 -0
  116. data/lib/cocoapods-tt/native/version_metadata.rb +26 -0
  117. data/lib/cocoapods-tt/native/xcode/framework_paths.rb +54 -0
  118. data/lib/cocoapods-tt/native/xcode/linkage_analyzer.rb +22 -0
  119. data/lib/cocoapods-tt/native/xcode/xcframework/xcframework_slice.rb +138 -0
  120. data/lib/cocoapods-tt/native/xcode/xcframework.rb +99 -0
  121. data/lib/cocoapods-tt/native/xcode.rb +7 -0
  122. data/lib/cocoapods-tt.rb +1 -0
  123. data/lib/cocoapods_plugin.rb +17 -0
  124. metadata +193 -0
@@ -0,0 +1,135 @@
1
+ module Pod
2
+ class Installer
3
+ # Context object designed to be used with the HooksManager which describes
4
+ # the context of the installer.
5
+ #
6
+ class BaseInstallHooksContext
7
+ # @return [Sandbox] The Sandbox for the project.
8
+ #
9
+ attr_reader :sandbox
10
+
11
+ # @return [String] The path to the sandbox root (`Pods` directory).
12
+ #
13
+ attr_reader :sandbox_root
14
+
15
+ # @return [Xcodeproj::Project] The Pods Xcode project.
16
+ #
17
+ attr_reader :pods_project
18
+
19
+ # @return [Array<UmbrellaTargetDescription>] The list of
20
+ # the CocoaPods umbrella targets generated by the installer.
21
+ #
22
+ attr_reader :umbrella_targets
23
+
24
+ # Initialize a new instance
25
+ #
26
+ # @param [Sandbox] sandbox see #sandbox
27
+ # @param [String] sandbox_root see #sandbox_root
28
+ # @param [Xcodeproj::Project] pods_project see #pods_project
29
+ # @param [Array<UmbrellaTargetDescription>] umbrella_targets see #umbrella_targets
30
+ #
31
+ def initialize(sandbox, sandbox_root, pods_project, umbrella_targets)
32
+ @sandbox = sandbox
33
+ @sandbox_root = sandbox_root
34
+ @pods_project = pods_project
35
+ @umbrella_targets = umbrella_targets
36
+ end
37
+
38
+ # @return [PostInstallHooksContext] Convenience class generator method
39
+ #
40
+ # @param [Sandbox] sandbox
41
+ # The sandbox
42
+ #
43
+ # @param [Project] pods_project
44
+ # The pods project.
45
+ #
46
+ # @param [Array<AggregateTarget>] aggregate_targets
47
+ # The aggregate targets, which will been presented by an adequate
48
+ # {UmbrellaTargetDescription} in the generated context.
49
+ #
50
+ # @return [HooksContext] Convenience class method to generate the
51
+ # static context.
52
+ #
53
+ def self.generate(sandbox, pods_project, aggregate_targets)
54
+ umbrella_targets_descriptions = aggregate_targets.map do |umbrella|
55
+ user_project = umbrella.user_project
56
+ user_targets = umbrella.user_targets
57
+ specs = umbrella.specs
58
+ platform_name = umbrella.platform.name
59
+ platform_deployment_target = umbrella.platform.deployment_target.to_s
60
+ cocoapods_target_label = umbrella.label
61
+ UmbrellaTargetDescription.new(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
62
+ end
63
+
64
+ new(sandbox, sandbox.root.to_s, pods_project, umbrella_targets_descriptions)
65
+ end
66
+
67
+ # Pure data class which describes an umbrella target.
68
+ #
69
+ class UmbrellaTargetDescription
70
+ # @return [Xcodeproj::Project] The user project into which this target
71
+ # is integrated.
72
+ #
73
+ attr_reader :user_project
74
+
75
+ # @return [Array<PBXNativeTarget>]
76
+ # The list of user targets integrated by this umbrella target.
77
+ #
78
+ attr_reader :user_targets
79
+
80
+ # @return [Array<Specification>] The list of the
81
+ # specifications of the target.
82
+ #
83
+ attr_reader :specs
84
+
85
+ # @return [Symbol] The platform (either `:ios`, `:watchos`, `:tvos`, or `:osx`).
86
+ #
87
+ attr_reader :platform_name
88
+
89
+ # @return [String] The deployment target.
90
+ #
91
+ attr_reader :platform_deployment_target
92
+
93
+ # @return [String] The label for the target.
94
+ #
95
+ attr_reader :cocoapods_target_label
96
+
97
+ # Initialize a new instance
98
+ #
99
+ # @param [Xcodeproj::Project] user_project see #user_project
100
+ # @param [Array<PBXNativeTarget>] user_targets see #user_targets
101
+ # @param [Array<Specification>] specs see #specs
102
+ # @param [Symbol] platform_name see #platform_name
103
+ # @param [String] platform_deployment_target see #platform_deployment_target
104
+ # @param [String] cocoapods_target_label see #cocoapods_target_label
105
+ #
106
+ def initialize(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
107
+ @user_project = user_project
108
+ @user_targets = user_targets
109
+ @specs = specs
110
+ @platform_name = platform_name
111
+ @platform_deployment_target = platform_deployment_target
112
+ @cocoapods_target_label = cocoapods_target_label
113
+ end
114
+
115
+ # @return [String] The path of the user project
116
+ # integrated by this target.
117
+ #
118
+ def user_project_path
119
+ user_project.path if user_project
120
+ end
121
+
122
+ # @return [Array<String>] The list of the UUIDs of the
123
+ # user targets integrated by this umbrella
124
+ # target. They can be used to find the
125
+ # targets opening the project They can be used
126
+ # to find the targets opening the project with
127
+ # Xcodeproj.
128
+ #
129
+ def user_target_uuids
130
+ user_targets.map(&:uuid)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,195 @@
1
+ require 'active_support/hash_with_indifferent_access'
2
+
3
+ module Pod
4
+ class Installer
5
+ # Represents the installation options the user can customize via a
6
+ # `Podfile`.
7
+ #
8
+ class InstallationOptions
9
+ # Parses installation options from a podfile.
10
+ #
11
+ # @param [Podfile] podfile the podfile to parse installation options
12
+ # from.
13
+ #
14
+ # @raise [Informative] if `podfile` does not specify a `CocoaPods`
15
+ # install.
16
+ #
17
+ # @return [Self]
18
+ #
19
+ def self.from_podfile(podfile)
20
+ name, options = podfile.installation_method
21
+ unless name.downcase == 'cocoapods'
22
+ raise Informative, "Currently need to specify a `cocoapods` install, you chose `#{name}`."
23
+ end
24
+ new(options)
25
+ end
26
+
27
+ # Defines a new installation option.
28
+ #
29
+ # @param [#to_s] name the name of the option.
30
+ #
31
+ # @param default the default value for the option.
32
+ #
33
+ # @param [Boolean] boolean whether the option has a boolean value.
34
+ #
35
+ # @return [void]
36
+ #
37
+ # @!macro [attach] option
38
+ #
39
+ # @note this option defaults to $2.
40
+ #
41
+ # @return [Boolean] the $1 $0 for installation.
42
+ #
43
+ def self.option(name, default, boolean: true)
44
+ name = name.to_s
45
+ raise ArgumentError, "The `#{name}` option is already defined" if defaults.key?(name)
46
+ defaults[name] = default
47
+ attr_accessor name
48
+ alias_method "#{name}?", name if boolean
49
+ end
50
+
51
+ # @return [Hash<Symbol,Object>] all known installation options and their
52
+ # default values.
53
+ #
54
+ def self.defaults
55
+ @defaults ||= {}
56
+ end
57
+
58
+ # @return [Array<Symbol>] the names of all known installation options.
59
+ #
60
+ def self.all_options
61
+ defaults.keys
62
+ end
63
+
64
+ # Initializes the installation options with a hash of options from a
65
+ # Podfile.
66
+ #
67
+ # @param [Hash] options the options to parse.
68
+ #
69
+ # @raise [Informative] if `options` contains any unknown keys.
70
+ #
71
+ def initialize(options = {})
72
+ options = ActiveSupport::HashWithIndifferentAccess.new(options)
73
+ unknown_keys = options.keys - self.class.all_options.map(&:to_s)
74
+ raise Informative, "Unknown installation options: #{unknown_keys.to_sentence}." unless unknown_keys.empty?
75
+ self.class.defaults.each do |key, default|
76
+ value = options.fetch(key, default)
77
+ send("#{key}=", value)
78
+ end
79
+ end
80
+
81
+ # @param [Boolean] include_defaults whether values that match the default
82
+ # for their option should be included. Defaults to `true`.
83
+ #
84
+ # @return [Hash] the options, keyed by option name.
85
+ #
86
+ def to_h(include_defaults: true)
87
+ self.class.defaults.reduce(ActiveSupport::HashWithIndifferentAccess.new) do |hash, (option, default)|
88
+ value = send(option)
89
+ hash[option] = value if include_defaults || value != default
90
+ hash
91
+ end
92
+ end
93
+
94
+ def ==(other)
95
+ other.is_a?(self.class) && to_h == other.to_h
96
+ end
97
+
98
+ alias_method :eql, :==
99
+
100
+ def hash
101
+ to_h.hash
102
+ end
103
+
104
+ # Whether to clean the sources of the pods during installation
105
+ #
106
+ # Cleaning removes any files not used by the pod as specified by the podspec and the platforms
107
+ # that the project supports
108
+ #
109
+ # @see {PodSourceInstaller#clean!}
110
+ #
111
+ option :clean, true
112
+
113
+ # Whether to deduplicate pod targets
114
+ #
115
+ # Target deduplication adds suffixes to pod targets for the cases where a pod is included
116
+ # in multiple targets that have different requirements. For example, a pod named 'MyPod' with a subspec 'SubA'
117
+ # that is included in two targets as follows:
118
+ #
119
+ # target 'MyTargetA' do
120
+ # pod 'MyPod/SubA'
121
+ # end
122
+ #
123
+ # target 'MyTargetB' do
124
+ # pod 'MyPod'
125
+ # end
126
+ #
127
+ # will result in two Pod targets: `MyPod` and `MyPod-SubA`
128
+ #
129
+ option :deduplicate_targets, true
130
+
131
+ # Whether to generate deterministic UUIDs when creating the Pods project
132
+ #
133
+ # @see {Xcodeproj#generate_uuid}
134
+ #
135
+ option :deterministic_uuids, true
136
+
137
+ # Whether to integrate the installed pods into the user project
138
+ #
139
+ # If set to false, Pods will be downloaded and installed to the `Pods/` directory
140
+ # but they will not be integrated into your project.
141
+ #
142
+ option :integrate_targets, true
143
+
144
+ # Whether to lock the source files of pods. Xcode will prompt to unlock the files when attempting to modify
145
+ # their contents
146
+ #
147
+ # @note There is a performance penalty to locking the pods during installation. If this is significantly
148
+ # impacting the duration of `pod install` for your project, you can try setting this to `false`
149
+ #
150
+ option :lock_pod_sources, true
151
+
152
+ # Whether to emit a warning when multiple sources contain a Pod with the same name and version
153
+ #
154
+ option :warn_for_multiple_pod_sources, true
155
+
156
+ # Whether to emit a warning if a project is not explicitly specifying the git based master specs repo and can
157
+ # instead use CDN which is the default.
158
+ #
159
+ option :warn_for_unused_master_specs_repo, true
160
+
161
+ # Whether to share Xcode schemes for development pods.
162
+ #
163
+ # Schemes for development pods are created automatically but are not shared by default.
164
+ #
165
+ option :share_schemes_for_development_pods, false
166
+
167
+ # Whether to disable the input & output paths of the CocoaPods script phases (Copy Frameworks & Copy Resources)
168
+ #
169
+ # @see https://github.com/CocoaPods/CocoaPods/issues/8073
170
+ #
171
+ option :disable_input_output_paths, false
172
+
173
+ # Whether to preserve the file structure of all Pods, including externally sourced pods.
174
+ #
175
+ # By default, the file structure of Pod sources is preserved only for development pods. Setting
176
+ # `:preserve_pod_file_structure` to `true` will _always_ preserve the file structure.
177
+ #
178
+ option :preserve_pod_file_structure, false
179
+
180
+ # Whether to generate a project per pod target. Instead of creating 1 `Pods.xcodeproj`, this option will generate
181
+ # a project for every pod target that will be nested under the `Pods.xcodeproj`.
182
+ #
183
+ option :generate_multiple_pod_projects, false
184
+
185
+ # Whether to enable only regenerating targets and their associate projects that have changed
186
+ # since the previous installation.
187
+ #
188
+ option :incremental_installation, false
189
+
190
+ # Whether to skip generating the `Pods.xcodeproj` and perform only dependency resolution and downloading.
191
+ #
192
+ option :skip_pods_project_generation, false
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,224 @@
1
+ require 'active_support/core_ext/string/strip'
2
+
3
+ module Pod
4
+ class Installer
5
+ # Controller class responsible of installing the activated specifications
6
+ # of a single Pod.
7
+ #
8
+ # @note This class needs to consider all the activated specs of a Pod.
9
+ #
10
+ class PodSourceInstaller
11
+ UNENCRYPTED_PROTOCOLS = %w(http git).freeze
12
+
13
+ # @return [Sandbox] The installation target.
14
+ #
15
+ attr_reader :sandbox
16
+
17
+ # @return [Podfile] the podfile that should be integrated with the user
18
+ # projects.
19
+ #
20
+ attr_reader :podfile
21
+
22
+ # @return [Hash{Symbol=>Array}] The specifications that need to be
23
+ # installed grouped by platform.
24
+ #
25
+ attr_reader :specs_by_platform
26
+
27
+ # @return [Boolean] Whether the installer is allowed to touch the cache.
28
+ #
29
+ attr_reader :can_cache
30
+ alias_method :can_cache?, :can_cache
31
+
32
+ # Initialize a new instance
33
+ #
34
+ # @param [Sandbox] sandbox @see #sandbox
35
+ # @param [Podfile] podfile @see #podfile
36
+ # @param [Hash{Symbol=>Array}] specs_by_platform @see #specs_by_platform
37
+ # @param [Boolean] can_cache @see #can_cache
38
+ #
39
+ def initialize(sandbox, podfile, specs_by_platform, can_cache: true)
40
+ @sandbox = sandbox
41
+ @podfile = podfile
42
+ @specs_by_platform = specs_by_platform
43
+ @can_cache = can_cache
44
+ end
45
+
46
+ # @return [String] A string suitable for debugging.
47
+ #
48
+ def inspect
49
+ "<#{self.class} sandbox=#{sandbox.root} pod=#{root_spec.name}"
50
+ end
51
+
52
+ # @return [String] The name of the pod this installer is installing.
53
+ #
54
+ def name
55
+ root_spec.name
56
+ end
57
+
58
+ #-----------------------------------------------------------------------#
59
+
60
+ public
61
+
62
+ # @!group Installation
63
+
64
+ # Creates the target in the Pods project and the relative support files.
65
+ #
66
+ # @return [void]
67
+ #
68
+ def install!
69
+ download_source unless predownloaded? || local?
70
+ PodSourcePreparer.new(root_spec, root).prepare! if local?
71
+ sandbox.remove_local_podspec(name) unless predownloaded? || local? || external?
72
+ end
73
+
74
+ # Cleans the installations if appropriate.
75
+ #
76
+ # Cleaning the installation will remove any files that are not used during the build process, based on
77
+ # the podspec and platforms of the target that the pod is integrated into.
78
+ #
79
+ # @see {#clean_installation}
80
+ #
81
+ # @return [void]
82
+ #
83
+ def clean!
84
+ clean_installation unless local?
85
+ end
86
+
87
+ # Locks the source files if appropriate.
88
+ #
89
+ # @return [void]
90
+ #
91
+ def lock_files!(file_accessors)
92
+ return if local?
93
+ unlocked_files = source_files(file_accessors).reject { |f| (File.stat(f).mode & 0o200).zero? }
94
+ FileUtils.chmod('u-w', unlocked_files)
95
+ end
96
+
97
+ # Unlocks the source files if appropriate.
98
+ #
99
+ # @return [void]
100
+ #
101
+ def unlock_files!(file_accessors)
102
+ return if local?
103
+ FileUtils.chmod('u+w', source_files(file_accessors))
104
+ end
105
+
106
+ #-----------------------------------------------------------------------#
107
+
108
+ private
109
+
110
+ # @!group Installation Steps
111
+
112
+ # Downloads the source of the Pod.
113
+ #
114
+ # @return [void]
115
+ #
116
+ def download_source
117
+ verify_source_is_secure(root_spec)
118
+ download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
119
+
120
+ if (specific_source = download_result.checkout_options) && specific_source != root_spec.source
121
+ sandbox.store_checkout_source(root_spec.name, specific_source)
122
+ end
123
+ end
124
+
125
+ # Verify the source of the spec is secure, which is used to show a warning to the user if that isn't the case
126
+ # This method doesn't verify all protocols, but currently only prohibits unencrypted 'http://' and 'git://''
127
+ # connections.
128
+ #
129
+ # @return [void]
130
+ #
131
+ def verify_source_is_secure(root_spec)
132
+ return if root_spec.source.nil? || (root_spec.source[:http].nil? && root_spec.source[:git].nil?)
133
+ source = if !root_spec.source[:http].nil?
134
+ URI(root_spec.source[:http].to_s)
135
+ elsif !root_spec.source[:git].nil?
136
+ git_source = root_spec.source[:git].to_s
137
+ return unless git_source =~ /^#{URI.regexp}$/
138
+ URI(git_source)
139
+ end
140
+ if UNENCRYPTED_PROTOCOLS.include?(source.scheme) && source.host != 'localhost'
141
+ UI.warn "'#{root_spec.name}' uses the unencrypted '#{source.scheme}' protocol to transfer the Pod. " \
142
+ 'Please be sure you\'re in a safe network with only trusted hosts. ' \
143
+ 'Otherwise, please reach out to the library author to notify them of this security issue.'
144
+ end
145
+ end
146
+
147
+ def download_request
148
+ Downloader::Request.new(
149
+ :spec => root_spec,
150
+ :released => released?,
151
+ )
152
+ end
153
+
154
+ #-----------------------------------------------------------------------#
155
+
156
+ private
157
+
158
+ # Removes all the files not needed for the installation according to the
159
+ # specs by platform.
160
+ #
161
+ # @return [void]
162
+ #
163
+ def clean_installation
164
+ cleaner = Sandbox::PodDirCleaner.new(root, specs_by_platform)
165
+ cleaner.clean!
166
+ end
167
+
168
+ # @!group Convenience methods.
169
+
170
+ # @return [Array<Specifications>] the specification of the Pod used in
171
+ # this installation.
172
+ #
173
+ def specs
174
+ specs_by_platform.values.flatten
175
+ end
176
+
177
+ # @return [Specification] the root specification of the Pod.
178
+ #
179
+ def root_spec
180
+ specs.first.root
181
+ end
182
+
183
+ # @return [Pathname] the folder where the source of the Pod is located.
184
+ #
185
+ def root
186
+ sandbox.pod_dir(root_spec.name)
187
+ end
188
+
189
+ # @return [Boolean] whether the source has been pre downloaded in the
190
+ # resolution process to retrieve its podspec.
191
+ #
192
+ def predownloaded?
193
+ sandbox.predownloaded_pods.include?(root_spec.name)
194
+ end
195
+
196
+ # @return [Boolean] whether the pod uses the local option and thus
197
+ # CocoaPods should not interfere with the files of the user.
198
+ #
199
+ def local?
200
+ sandbox.local?(root_spec.name)
201
+ end
202
+
203
+ # @return [Boolean] whether the pod uses an external source (e.g. :podspec) in the
204
+ # resolution process to retrieve its podspec.
205
+ #
206
+ def external?
207
+ @dependencies ||= podfile.dependencies.select(&:external?).map(&:name)
208
+ @dependencies.include?(root_spec.name)
209
+ end
210
+
211
+ def released?
212
+ !local? && !predownloaded? && sandbox.specification(root_spec.name) != root_spec
213
+ end
214
+
215
+ # @return [Array<Pathname>] The paths of the source files
216
+ #
217
+ def source_files(file_accessors)
218
+ file_accessors.flat_map(&:source_files)
219
+ end
220
+
221
+ #-----------------------------------------------------------------------#
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,77 @@
1
+ module Pod
2
+ class Installer
3
+ # Controller class responsible of executing the prepare command
4
+ # of a single Pod.
5
+ #
6
+ class PodSourcePreparer
7
+ # @return [Specification] the root specification of the Pod.
8
+ #
9
+ attr_reader :spec
10
+
11
+ # @return [Pathname] the folder where the source of the Pod is located.
12
+ #
13
+ attr_reader :path
14
+
15
+ # Initialize a new instance
16
+ #
17
+ # @param [Specification] spec the root specification of the Pod.
18
+ # @param [Pathname] path the folder where the source of the Pod is located.
19
+ #
20
+ def initialize(spec, path)
21
+ raise "Given spec isn't a root spec, but must be." unless spec.root?
22
+ @spec = spec
23
+ @path = path
24
+ end
25
+
26
+ #-----------------------------------------------------------------------#
27
+
28
+ public
29
+
30
+ # @!group Preparation
31
+
32
+ # Executes the prepare command if there is one.
33
+ #
34
+ # @return [void]
35
+ #
36
+ def prepare!
37
+ run_prepare_command
38
+ end
39
+
40
+ #-----------------------------------------------------------------------#
41
+
42
+ private
43
+
44
+ # @!group Preparation Steps
45
+
46
+ extend Executable
47
+ executable :bash
48
+
49
+ # Runs the prepare command bash script of the spec.
50
+ #
51
+ # @note Unsets the `CDPATH` env variable before running the
52
+ # shell script to avoid issues with relative paths
53
+ # (issue #1694).
54
+ #
55
+ # @return [void]
56
+ #
57
+ def run_prepare_command
58
+ return unless spec.prepare_command
59
+ UI.section(' > Running prepare command', '', 1) do
60
+ Dir.chdir(path) do
61
+ begin
62
+ ENV.delete('CDPATH')
63
+ ENV['COCOAPODS_VERSION'] = Pod::VERSION
64
+ prepare_command = spec.prepare_command.strip_heredoc.chomp
65
+ full_command = "\nset -e\n" + prepare_command
66
+ bash!('-c', full_command)
67
+ ensure
68
+ ENV.delete('COCOAPODS_VERSION')
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ #-----------------------------------------------------------------------#
75
+ end
76
+ end
77
+ end