1
+ # Similar to:
2
+ # https://github.com/CocoaPods/CocoaPods/blob/master/lib/cocoapods/external_sources/abstract_external_source.rb
3
+ require 'cocoapods-embed-flutter/flutter/downloader'
4
+ require 'cocoapods'
5
+
6
+ module Flutter
7
+ module Pub
8
+ module ExternalSources
9
+ SOURCE_KEYS = {
10
+ :git => [ :tag , :branch , :commit , :submodules ] . freeze ,
11
+ :svn => [ :folder , :tag , :revision ] . freeze ,
12
+ :hg => [ :revision ] . freeze ,
13
+ :http => [ :flatten , :type , :sha256 , :sha1 , :headers ] . freeze ,
14
+ } . freeze
15
+
16
+ def self . fetchWithNameAndOptions ( name , options )
17
+ raise StandardError , 'A flutter module requires a name.' unless name
18
+
19
+ options = options . last if options . is_a? ( Array )
20
+ raise StandardError , "No options specified for flutter module: '#{ name } '." unless options . is_a? ( Hash )
21
+
22
+ if options . key? ( :path )
23
+ path = options [ :path ]
24
+ elsif SOURCE_KEYS . keys . any? { |key | options . key? ( key ) }
25
+ source = DownloaderSource . new ( name , options , Pod ::Config . instance . podfile_path )
26
+ source . fetch ( Pod ::Config . instance . sandbox )
27
+ path = source . normalized_pupspec_path
28
+ else
29
+ raise StandardError , "Invalid flutter module: '#{ name } '."
30
+ end
31
+
32
+ return Spec . find ( name , path )
33
+ end
34
+
35
+ # Provides support for fetching a specification file from a source handled
36
+ # by the downloader. Supports all the options of the downloader
37
+ #
38
+ # @note The pubspec must be in the root of the repository
39
+ # or in directory with the name provided
40
+ #
41
+ class DownloaderSource
42
+ # @return [String] the name of the Package described by this external source.
43
+ #
44
+ attr_reader :name
45
+
46
+ # @return [Hash{Symbol => String}] the hash representation of the
47
+ # external source.
48
+ #
49
+ attr_reader :params
50
+
51
+ # @return [String] the path where the podfile is defined to resolve
52
+ # relative paths.
53
+ #
54
+ attr_reader :podfile_path
55
+
56
+ # @return [Boolean] Whether the source is allowed to touch the cache.
57
+ #
58
+ attr_reader :can_cache
59
+ alias_method :can_cache? , :can_cache
60
+
61
+ # Initialize a new instance
62
+ #
63
+ # @param [String] name @see #name
64
+ # @param [Hash] params @see #params
65
+ # @param [String] podfile_path @see #podfile_path
66
+ # @param [Boolean] can_cache @see #can_cache
67
+ #
68
+ def initialize ( name , params , podfile_path , can_cache = true )
69
+ @name = name
70
+ @params = params
71
+ @podfile_path = podfile_path
72
+ @can_cache = can_cache
73
+ end
74
+
75
+ # @return [Boolean] whether an external source source is equal to another
76
+ # according to the {#name} and to the {#params}.
77
+ #
78
+ def ==( other )
79
+ return false if other . nil?
80
+ name == other . name && params == other . params
81
+ end
82
+
83
+
84
+ public
85
+
86
+ # @!group Subclasses hooks
87
+
88
+ # Fetches the external source from the remote according to the params.
89
+ #
90
+ # @param [Sandbox] sandbox
91
+ # the sandbox where the specification should be stored.
92
+ #
93
+ # @return [void]
94
+ #
95
+ def fetch ( sandbox )
96
+ pre_download ( sandbox )
97
+ end
98
+
99
+ # @return [String] a string representation of the source suitable for UI.
100
+ #
101
+ def description
102
+ strategy = Pod ::Downloader . strategy_from_options ( params )
103
+ options = params . dup
104
+ url = options . delete ( strategy )
105
+ result = "from `#{ url } `"
106
+ options . each do |key , value |
107
+ result << ", #{ key } `#{ value } `"
108
+ end
109
+ result
110
+ end
111
+
112
+ # Return the normalized path for a pubspec for a relative declared path.
113
+ #
114
+ # @param [String] declared_path
115
+ # The path declared in the podfile.
116
+ #
117
+ # @return [String] The uri of the pubspec appending the name of the file
118
+ # and expanding it if necessary.
119
+ #
120
+ # @note If the declared path is expanded only if the represents a path
121
+ # relative to the file system.
122
+ #
123
+ def normalized_pupspec_path ( declared_path )
124
+ Spec . find_file ( name , declared_path )
125
+ end
126
+
127
+ def normalized_pupspec_path
128
+ Spec . find_file ( name , target )
129
+ end
130
+
131
+ private
132
+
133
+ # @! Subclasses helpers
134
+
135
+ # Pre-downloads a Pod passing the options to the downloader and informing
136
+ # the sandbox.
137
+ #
138
+ # @param [Sandbox] sandbox
139
+ # The sandbox where the Pod should be downloaded.
140
+ #
141
+ # @note To prevent a double download of the repository the pod is
142
+ # marked as pre-downloaded indicating to the installer that only
143
+ # clean operations are needed.
144
+ #
145
+ # @todo The downloader configuration is the same of the
146
+ # #{PodSourceInstaller} and it needs to be kept in sync.
147
+ #
148
+ # @return [void]
149
+ #
150
+ def pre_download ( sandbox )
151
+ title = "Pre-downloading: `#{ name } ` #{ description } "
152
+ Pod ::UI . titled_section ( title , :verbose_prefix => '-> ' ) do
153
+ begin
154
+ download_result = Downloader . download ( download_request , target , :can_cache => can_cache )
155
+ rescue Pod ::DSLError => e
156
+ raise Pod ::Informative , "Failed to load '#{ name } ' pubspec: #{ e . message } "
157
+ rescue => e
158
+ raise Pod ::Informative , "Failed to download '#{ name } ': #{ e . message } "
159
+ end
160
+
161
+ # spec = download_result.spec
162
+ # raise Pod::Informative, "Unable to find a specification for '#{name}'." unless spec
163
+
164
+ # since the podspec might be cleaned, we want the checksum to refer
165
+ # to the json in the sandbox
166
+ # spec.defined_in_file = nil
167
+
168
+ # store_podspec(sandbox, spec)
169
+ # sandbox.store_pre_downloaded_pod(name)
170
+ # sandbox.store_checkout_source(name, download_result.checkout_options)
171
+ end
172
+ end
173
+
174
+ def download_request
175
+ Pod ::Downloader ::Request . new (
176
+ :name => name ,
177
+ :params => params ,
178
+ )
179
+ end
180
+
181
+ def target
182
+ return Pod ::Config . instance . sandbox . pod_dir ( name )
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
0 commit comments