lg_pod_plugin 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,16 +3,16 @@ require 'git'
3
3
  require 'cgi'
4
4
  require 'sqlite3'
5
5
  require 'cocoapods'
6
+ require_relative 'request'
6
7
  require_relative 'database'
7
8
  require_relative 'download'
8
9
  require_relative 'git_util'
9
- require_relative 'pod_spec'
10
10
 
11
11
  module LgPodPlugin
12
12
 
13
13
  class Installer
14
14
 
15
- REQUIRED_ATTRS ||= %i[name version options profile target real_name downloader git_util].freeze
15
+ REQUIRED_ATTRS ||= %i[name version options target real_name workspace].freeze
16
16
  attr_accessor(*REQUIRED_ATTRS)
17
17
 
18
18
  def initialize(profile, name, *requirements)
@@ -22,12 +22,11 @@ module LgPodPlugin
22
22
  self.name = name
23
23
  end
24
24
  self.real_name = name
25
- self.profile = profile
26
- self.git_util = GitUtil.new
27
- self.downloader = Downloader.new
25
+ self.workspace = profile.send(:defined_in_file).dirname
28
26
  self.target = profile.send(:current_target_definition)
29
27
 
30
28
  unless requirements && !requirements.empty?
29
+ LRequest.shared.setup_pod_info(self.name, self.workspace, nil)
31
30
  self.lg_pod(self.real_name, requirements)
32
31
  return
33
32
  end
@@ -38,38 +37,52 @@ module LgPodPlugin
38
37
  elsif "#{first.class}" == "Hash"
39
38
  self.options = first
40
39
  end
41
-
42
- hash_map = requirements[0].last
43
- if "#{hash_map.class}" == "Hash"
44
- self.options = hash_map
40
+ hash_map = nil
41
+ last = requirements[0].last
42
+ if "#{last.class}" == "Hash"
43
+ hash_map = last
44
+ end
45
+ git = hash_map[:git]
46
+ if hash_map && git
47
+ tag = hash_map[:tag]
48
+ branch = hash_map[:branch]
49
+ commit = hash_map[:commit]
50
+ if tag
51
+ hash_map.delete(:branch)
52
+ hash_map.delete(:commit)
53
+ elsif commit
54
+ hash_map.delete(:tag)
55
+ hash_map.delete(:branch)
56
+ elsif branch
57
+ hash_map.delete(:tag)
58
+ hash_map.delete(:commit)
59
+ end
45
60
  end
46
-
61
+ self.options = hash_map
62
+ LRequest.shared.setup_pod_info(self.name, self.workspace, hash_map)
47
63
  self.lg_pod(name, requirements)
48
-
49
64
  end
50
65
 
51
66
  public
52
- # @param [Object] name
53
- # @param [Hash] options
54
- # @return [Object] nil
55
67
  def lg_pod(name, *requirements)
56
68
  unless name
57
69
  raise StandardError, 'A dependency requires a name.'
58
70
  end
59
71
 
72
+ # 根据pod name安装, pod 'AFNetworking'
60
73
  if !requirements
61
74
  self.target.store_pod(self.real_name)
62
75
  return
63
76
  end
64
-
77
+ # 根据name, verison 安装, pod 'AFNetworking', "1.0.1"
65
78
  if self.version && !self.options
66
79
  self.target.store_pod(self.real_name, self.version)
67
80
  return
68
81
  end
69
-
82
+ # 根据name, verison 安装, pod 'AFNetworking', "1.0.1", :configurations => ["Debug"]
70
83
  if self.version && self.options
71
84
  hash_map = self.options
72
- hash_map.delete(:depth)
85
+ # hash_map.delete(:cache)
73
86
  self.target.store_pod(self.real_name, self.version, hash_map)
74
87
  return
75
88
  end
@@ -80,85 +93,47 @@ module LgPodPlugin
80
93
  return
81
94
  end
82
95
 
83
- real_path = nil
84
- tag = hash_map[:tag]
85
- url = hash_map[:git]
86
96
  path = hash_map[:path]
87
- commit = hash_map[:commit]
88
- branch = hash_map[:branch]
89
- is_cache = options[:depth]
90
97
  if path
91
- profile_path = self.profile.send(:defined_in_file).dirname
92
- real_path = Pathname.new(path).expand_path(profile_path)
93
- end
94
- # 找到本地组件库 执行 git pull
95
- if real_path && File.directory?(real_path)
96
- hash_map[:path] = real_path
97
- hash_map.delete(:depth)
98
- self.install_local_pod(self.name, hash_map)
98
+ self.install_local_pod(name, path, options)
99
99
  return
100
100
  end
101
-
102
- # 根据tag, commit下载文件
103
101
  hash_map.delete(:path)
104
- if (tag && url) || (commit && url)
105
- hash_map.delete(:depth)
106
- hash_map.delete(:branch)
102
+ git = hash_map[:git]
103
+ # 根据git_url 下载远程仓库
104
+ if git
105
+ LRequest.shared.downloader.pre_download_pod
106
+ # hash_map.delete(:cache)
107
107
  self.target.store_pod(self.real_name, hash_map)
108
- return
109
- end
110
-
111
- # 根据 branch 下载代码
112
- if url
113
- hash_map.delete(:tag)
114
- hash_map.delete(:commit)
115
- self.downloader.download_init(self.name, hash_map)
116
- self.downloader.pre_download_pod(self.git_util)
117
- hash_map.delete(:depth)
108
+ else
109
+ #hash_map.delete(:cache)
118
110
  self.target.store_pod(self.real_name, hash_map)
119
111
  end
120
112
 
121
-
122
113
  end
123
114
 
124
115
  public
125
- def install_form_specs(spec_path = nil)
126
- spec_path ||= './Specs'
127
- path = File.expand_path(spec_path, Dir.pwd)
128
- file_objects = Dir.glob(File.expand_path("*.rb", path)).map do |file_path|
129
- #读取 xxx.rb文件
130
- Spec.form_file(file_path)
131
- end
132
- # 便利出每一个pod对安装信息
133
- file_objects.each do |file|
134
- if file.install
135
- options = file.pod_requirements
136
- self.lg_pod(file.name, options)
137
- end
138
- end
139
-
140
- end
141
-
142
- public
143
- def install_local_pod(name, options = {})
116
+ #安装本地pod
117
+ def install_local_pod(name, relative_path, options = {})
144
118
  hash_map = options
145
- local_path = options[:path]
146
119
  branch = options[:branch]
147
- unless Dir.glob(File.expand_path(".git", local_path)).count > 0
148
- LgPodPlugin.log_red("pod `#{name}` at path => #{local_path} 找不到.git目录")
120
+ absolute_path = Pathname.new(relative_path).expand_path(self.workspace)
121
+ unless absolute_path.exist?
122
+ LgPodPlugin.log_red("pod `#{name}` at path => #{relative_path} 找不到")
149
123
  return
150
124
  end
151
- unless Dir.glob(File.expand_path("#{name}.podspec", local_path)).count > 0
152
- LgPodPlugin.log_red("pod `#{name}` at path => #{local_path} 找不到#{name}.podspec文件")
125
+ unless Dir.glob(File.expand_path(".git", absolute_path)).count > 0
126
+ LgPodPlugin.log_red("pod `#{name}` at path => #{absolute_path} 找不到.git目录")
153
127
  return
154
128
  end
155
-
156
- self.git_util.git_init(name, :branch => branch, :path => local_path)
157
- self.git_util.git_local_pod_check(local_path)
158
- hash_map[:path] = local_path.to_path
129
+ unless Dir.glob(File.expand_path("#{name}.podspec", absolute_path)).count > 0
130
+ LgPodPlugin.log_red("pod `#{name}` at path => #{absolute_path} 找不到#{name}.podspec文件")
131
+ return
132
+ end
133
+ LRequest.shared.git_util.git_local_pod_check(absolute_path)
159
134
  hash_map.delete(:tag)
160
135
  hash_map.delete(:git)
161
- hash_map.delete(:depth)
136
+ # hash_map.delete(:cache)
162
137
  hash_map.delete(:commit)
163
138
  hash_map.delete(:branch)
164
139
  # 安装本地私有组件库
@@ -0,0 +1,237 @@
1
+ require 'git'
2
+ require 'cocoapods/downloader'
3
+ require 'cocoapods/downloader/cache'
4
+ require 'cocoapods/downloader/response'
5
+ require 'cocoapods/downloader/request'
6
+
7
+ module LgPodPlugin
8
+
9
+ class LCachePodInfo
10
+ REQUIRED_ATTRS ||= %i[sha tag name path branch timestamp].freeze
11
+ attr_accessor(*REQUIRED_ATTRS)
12
+
13
+ def initialize
14
+ super
15
+ end
16
+
17
+ end
18
+
19
+ class LCache
20
+ REQUIRED_ATTRS ||= %i[workspace cache_root].freeze
21
+ attr_accessor(*REQUIRED_ATTRS)
22
+
23
+ def initialize(workspace)
24
+ self.workspace = workspace
25
+ self.cache_root = LFileManager.cache_workspace(self.workspace)
26
+ end
27
+
28
+ #根据git branch commit 返回请求参数用来获取缓存 path
29
+ def get_request_params(name, git, branch, tag, commit)
30
+ options = { :git => git }
31
+ if git && tag
32
+ options[:tag] = tag
33
+ options[:commit] = commit
34
+ elsif git && branch
35
+ if commit
36
+ options[:commit] = commit
37
+ else
38
+ new_commit_id = LGitUtil.git_ls_remote_refs(git, branch, nil, commit)
39
+ options[:commit] = new_commit_id
40
+ end
41
+ elsif git && commit
42
+ options[:commit] = commit
43
+ end
44
+ return options
45
+ end
46
+ #判断缓存是否存在且有效命中缓存
47
+ def find_pod_cache(name, git, branch, tag, commit, is_update)
48
+ hash_map = nil
49
+ if is_update
50
+ hash_map = self.get_request_params(name, git, branch, tag, commit)
51
+ else
52
+ if LRequest.shared.lock_params
53
+ lock_tag = LRequest.shared.lock_params[:tag]
54
+ lock_branch = LRequest.shared.lock_params[:branch]
55
+ lock_commit = LRequest.shared.lock_params[:commit]
56
+ hash_map = self.get_request_params(name, git, lock_branch, lock_tag, lock_commit)
57
+ else
58
+ hash_map = self.get_request_params(name, git, branch, tag, commit)
59
+ end
60
+ end
61
+ request = LCache.download_request(name, hash_map)
62
+ destination = LCache.path_for_pod(request, {})
63
+ cache_pod_spec = LCache.path_for_spec(request, {})
64
+ if File.exist?(destination) && File.exist?(cache_pod_spec)
65
+ return false
66
+ else
67
+ return true
68
+ end
69
+ end
70
+
71
+ def self.root_path
72
+ path = File.join(Dir.home, "Library/Caches/CocoaPods/Pods")
73
+ Pathname(path)
74
+ end
75
+
76
+ def self.download_request(name, params)
77
+ Pod::Downloader::Request.new(spec: nil, released: false, name: name, params: params)
78
+ end
79
+
80
+ def self.path_for_pod(request, slug_opts = {})
81
+ root = self.root_path
82
+ root + request.slug(**slug_opts)
83
+ end
84
+
85
+ def self.path_for_spec(request, slug_opts = {})
86
+ root = self.root_path
87
+ path = root + 'Specs' + request.slug(**slug_opts)
88
+ Pathname.new(path.to_path + '.podspec.json')
89
+ end
90
+
91
+ def self.cached_spec(request)
92
+ path = path_for_spec(request)
93
+ path.file? && Specification.from_file(path)
94
+ rescue JSON::ParserError
95
+ nil
96
+ end
97
+
98
+ def self.get_local_spec(request, target)
99
+ result = Pod::Downloader::Response.new
100
+ result.location = target
101
+ if request.released_pod?
102
+ result.spec = request.spec
103
+ local_specs = { request.name => request.spec }
104
+ return [request, local_specs]
105
+ else
106
+ local_specs = {}
107
+ podspecs = Pod::Sandbox::PodspecFinder.new(target).podspecs
108
+ podspecs[request.name] = request.spec if request.spec
109
+ podspecs.each do |name, spec|
110
+ if request.name == name
111
+ result.spec = spec
112
+ local_specs[request.name] = spec
113
+ end
114
+ end
115
+ end
116
+
117
+ [result, local_specs]
118
+ end
119
+
120
+ def self.group_sub_specs_by_platform(spec)
121
+ specs_by_platform = {}
122
+ [spec, *spec.recursive_subspecs].each do |ss|
123
+ ss.available_platforms.each do |platform|
124
+ specs_by_platform[platform] ||= []
125
+ specs_by_platform[platform] << ss
126
+ end
127
+ end
128
+ specs_by_platform
129
+ end
130
+
131
+ def self.copy_and_clean(source, destination, spec)
132
+ specs_by_platform = group_sub_specs_by_platform(spec)
133
+ destination.parent.mkpath
134
+ self.write_lock(destination) do
135
+ FileUtils.rm_rf(destination)
136
+ FileUtils.cp_r(source, destination)
137
+ Pod::Installer::PodSourcePreparer.new(spec, destination).prepare!
138
+ Pod::Sandbox::PodDirCleaner.new(destination, specs_by_platform).clean!
139
+ end
140
+ end
141
+
142
+ def self.write_lock(location, &block)
143
+ self.lock(location, File::LOCK_EX, &block)
144
+ end
145
+
146
+ def self.lock(location, lock_type)
147
+ raise ArgumentError, 'no block given' unless block_given?
148
+ lockfile = "#{location}.lock"
149
+ f = nil
150
+ loop do
151
+ f.close if f
152
+ f = File.open(lockfile, File::CREAT, 0o644)
153
+ f.flock(lock_type)
154
+ break if self.valid_lock?(f, lockfile)
155
+ end
156
+ begin
157
+ yield location
158
+ ensure
159
+ if lock_type == File::LOCK_SH
160
+ f.flock(File::LOCK_EX)
161
+ File.delete(lockfile) if self.valid_lock?(f, lockfile)
162
+ else
163
+ File.delete(lockfile)
164
+ end
165
+ f.close
166
+ end
167
+ end
168
+
169
+ def self.valid_lock?(file, filename)
170
+ file.stat.ino == File.stat(filename).ino
171
+ rescue Errno::ENOENT
172
+ false
173
+ end
174
+
175
+ def self.write_spec(spec, path)
176
+ path.dirname.mkpath
177
+ Pod::Downloader::Cache.write_lock(path) do
178
+ path.open('w') { |f| f.write spec.to_pretty_json }
179
+ end
180
+ end
181
+
182
+ # 拷贝 pod 缓存文件到 sandbox
183
+ def self.cache_pod(name, target, options = {})
184
+ request = LCache.download_request(name, options)
185
+ result, pods_pecs = get_local_spec(request, target)
186
+ result.location = nil
187
+ pods_pecs.each do |s_name, s_spec|
188
+ destination = path_for_pod(request, {})
189
+ if !File.exist?(destination)
190
+ LgPodPlugin.log_green "Copying #{name} from `#{target}` to `#{destination}` "
191
+ copy_and_clean(target, destination, s_spec)
192
+ end
193
+ cache_pod_spec = path_for_spec(request, {})
194
+ if !File.exist?(cache_pod_spec)
195
+ write_spec(s_spec, cache_pod_spec)
196
+ end
197
+ if request.name == s_name
198
+ result.location = destination
199
+ end
200
+
201
+ end
202
+
203
+ end
204
+
205
+ # 根据下载参数生产缓存的路径
206
+ def get_download_path(name)
207
+ # hash_map = {:git => git}
208
+ # if git && tag
209
+ # hash_map[:tag] = tag
210
+ # elsif git && commit
211
+ # hash_map[:commit] = commit
212
+ # elsif git && branch
213
+ # hash_map[:commit] = commit
214
+ # end
215
+ # request = LCache.download_request(name, hash_map)
216
+ # self.slug(name, request.params, nil)
217
+ self.cache_root.join(name)
218
+ end
219
+
220
+ # 根据下载参数生产缓存目录
221
+ def slug(name, params, spec)
222
+ path = ""
223
+ checksum = spec&.checksum && '-' << spec.checksum[0, 5]
224
+ opts = params.to_a.sort_by(&:first).map { |k, v| "#{k}=#{v}" }.join('-')
225
+ digest = Digest::MD5.hexdigest(opts)
226
+ if digest
227
+ path += "#{digest}"
228
+ end
229
+ if checksum
230
+ path += "#{checksum}"
231
+ end
232
+ path
233
+ end
234
+
235
+ end
236
+
237
+ end
@@ -0,0 +1,26 @@
1
+
2
+ require_relative 'string'
3
+ require 'cocoapods/user_interface'
4
+
5
+ module LgPodPlugin
6
+
7
+ def self.log_red(msg)
8
+ Pod::CoreUI.puts msg.red
9
+ end
10
+
11
+ def self.log_blue(msg)
12
+ Pod::CoreUI.puts msg.blue
13
+ end
14
+
15
+ def self.log_green(msg)
16
+ Pod::CoreUI.puts msg.green
17
+ end
18
+
19
+ def self.log_yellow(msg)
20
+ Pod::CoreUI.puts msg.yellow
21
+ end
22
+
23
+ def self.log(msg)
24
+ Pod::CoreUI.puts msg
25
+ end
26
+ end
@@ -0,0 +1,141 @@
1
+ require 'singleton'
2
+ require 'yaml'
3
+ require_relative 'l_cache'
4
+ require_relative 'git_util'
5
+ require_relative 'download'
6
+ module LgPodPlugin
7
+
8
+ class LRequest
9
+ include Singleton
10
+ REQUIRED_ATTRS ||= %i[name options workspace cache downloader git_util lock_info lock_params is_update].freeze
11
+ attr_accessor(*REQUIRED_ATTRS)
12
+
13
+ def is_update_pod
14
+ cgi = CGI.new
15
+ command_keys = cgi.keys
16
+ unless command_keys.count > 0
17
+ return false
18
+ end
19
+ first_key = command_keys[0].to_s ||= ""
20
+ if first_key.include?("install")
21
+ false
22
+ elsif first_key.include?("update")
23
+ true
24
+ else
25
+ false
26
+ end
27
+ end
28
+
29
+ def get_lock_info
30
+ lock_file = self.workspace.join("Podfile.lock")
31
+ if lock_file.exist?
32
+ json = YAML.load_file(lock_file.to_path)
33
+ external_sources = json["EXTERNAL SOURCES"]
34
+ return external_sources
35
+ else
36
+ return nil
37
+ end
38
+ end
39
+
40
+ def get_lock_params(git, branch, tag, commit)
41
+ unless self.lock_info
42
+ return nil
43
+ end
44
+ current_pod_info = self.lock_info[name]
45
+ unless current_pod_info
46
+ return nil
47
+ end
48
+ lock_commit = current_pod_info[:commit]
49
+ if git && tag
50
+ lock_tag = current_pod_info[:tag]
51
+ if lock_tag == tag
52
+ return { :git => git, :commit => lock_commit, :tag => lock_tag }
53
+ else
54
+ return nil
55
+ end
56
+ elsif git && branch
57
+ lock_branch = current_pod_info[:branch]
58
+ if branch == lock_branch
59
+ return { :git => git, :commit => lock_commit, :branch => lock_branch}
60
+ else
61
+ return nil
62
+ end
63
+ elsif commit == lock_commit
64
+ return { :git => git, :commit => lock_commit }
65
+ else
66
+ return nil
67
+ end
68
+ end
69
+
70
+ def setup_pod_info(name, workspace, options = {})
71
+ self.name = name
72
+ hash_map = options
73
+ tag = hash_map[:tag]
74
+ git = hash_map[:git]
75
+ path = hash_map[:path]
76
+ commit = hash_map[:commit]
77
+ branch = hash_map[:branch]
78
+ self.workspace = workspace
79
+ self.is_update = self.is_update_pod
80
+ if self.lock_info == nil
81
+ self.lock_info = self.get_lock_info
82
+ end
83
+ self.lock_params = self.get_lock_params(git, branch, tag, commit)
84
+ if git && tag
85
+ if self.lock_params && !self.is_update
86
+ lock_tag = self.lock_params[:tag]
87
+ lock_commit = self.lock_params[:commit]
88
+ if lock_tag == tag && lock_commit
89
+ hash_map[:commit] = lock_commit
90
+ else
91
+ new_branch, new_commit = LGitUtil.git_ls_remote_refs(git, branch, tag,commit)
92
+ hash_map[:commit] = new_commit
93
+ end
94
+ else
95
+ new_branch, new_commit = LGitUtil.git_ls_remote_refs(git, branch, tag,commit)
96
+ hash_map[:commit] = new_commit
97
+ end
98
+ elsif git && commit
99
+ if self.lock_params && !self.is_update
100
+ hash_map[:commit] = commit
101
+ else
102
+ new_branch, new_commit = LGitUtil.git_ls_remote_refs(git, branch, tag, commit)
103
+ if new_commit
104
+ hash_map[:commit] = new_commit
105
+ end
106
+ if new_branch
107
+ hash_map[:branch] = new_branch
108
+ end
109
+ end
110
+ elsif git && branch
111
+ if self.lock_params && !self.is_update
112
+ lock_branch = self.lock_params[:branch]
113
+ lock_commit = self.lock_params[:commit]
114
+ if branch == lock_branch && lock_commit
115
+ hash_map[:commit] = lock_commit
116
+ else
117
+ new_branch, new_commit = LGitUtil.git_ls_remote_refs(git, branch, tag, commit)
118
+ hash_map[:commit] = new_commit
119
+ end
120
+ else
121
+ new_branch, new_commit = LGitUtil.git_ls_remote_refs(git, branch, tag, commit)
122
+ hash_map[:commit] = new_commit
123
+ end
124
+ else
125
+ new_branch, new_commit = LGitUtil.git_ls_remote_refs(git, branch, tag, commit)
126
+ hash_map[:commit] = new_commit
127
+ hash_map[:branch] = new_branch
128
+ end
129
+ self.options = hash_map
130
+ self.cache = LCache.new(self.workspace)
131
+ self.git_util = LGitUtil.new(name, hash_map)
132
+ self.downloader = LDownloader.new(name, hash_map)
133
+ end
134
+
135
+ def self.shared
136
+ return LRequest.instance
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,33 @@
1
+ module LgPodPlugin
2
+
3
+ class String
4
+ # colorization
5
+ def colorize(color_code)
6
+ "\e[#{color_code}m#{self}\e[0m"
7
+ end
8
+
9
+ def red
10
+ colorize(31)
11
+ end
12
+
13
+ def green
14
+ colorize(32)
15
+ end
16
+
17
+ def yellow
18
+ colorize(33)
19
+ end
20
+
21
+ def blue
22
+ colorize(34)
23
+ end
24
+
25
+ def pink
26
+ colorize(35)
27
+ end
28
+
29
+ def light_blue
30
+ colorize(36)
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module LgPodPlugin
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.4"
3
3
  end