cocoapods-nexus-downloader 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3c8c852aa349b236b4cf219847aff4876ab6540ba4951ad91be9c22b74992962
4
+ data.tar.gz: a6d6d9dcad0fc4979ca7f62f115b373a7e8cbdfe6c94940a0935b78ac69d17ec
5
+ SHA512:
6
+ metadata.gz: 3524e18e04501317d01dac4b987213ffcd8ae78b4f4c61e612f282db11ccb076abcf5357929cc7823e890ea457c136aeb4fc5ad59f1bfb1efc1a74edbf65a83c
7
+ data.tar.gz: f126a15e3b06df0fda848ecdbd7bac822bb6be55c86985d0d2b79392f8fc447544a795761aadf9fdc54fc877ae4111e4ff46c542a9189c177d73d922562c1dfb
@@ -0,0 +1,44 @@
1
+ module Pod
2
+ class Command
3
+ # This is an example of a cocoapods plugin adding a top-level subcommand
4
+ # to the 'pod' command.
5
+ #
6
+ # You can also create subcommands of existing or new commands. Say you
7
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
8
+ # (e.g. `pod list deprecated`), there are a few things that would need
9
+ # to change.
10
+ #
11
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
12
+ # the class to exist in the the Pod::Command::List namespace
13
+ # - change this class to extend from `List` instead of `Command`. This
14
+ # tells the plugin system that it is a subcommand of `list`.
15
+ # - edit `lib/cocoapods_plugins.rb` to require this file
16
+ #
17
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
18
+ # in the `plugins.json` file, once your plugin is released.
19
+ #
20
+ class Nexus < Command
21
+ self.summary = 'Short description of cocoapods-nexus.'
22
+
23
+ self.description = <<-DESC
24
+ Longer description of cocoapods-Nexus.
25
+ DESC
26
+
27
+ self.arguments = 'NAME'
28
+
29
+ def initialize(argv)
30
+ @name = argv.shift_argument
31
+ super
32
+ end
33
+
34
+ def validate!
35
+ super
36
+ help! 'A Pod name is required.' unless @name
37
+ end
38
+
39
+ def run
40
+ UI.puts "Add your implementation for the cocoapods-nexus plugin in #{__FILE__}"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-nexus-downloader/command/nexus'
@@ -0,0 +1,3 @@
1
+ module CocoapodsNexusDownloader
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,18 @@
1
+ require 'cocoapods-downloader'
2
+ require 'cocoapods-nexus-downloader/nexus-downloader'
3
+
4
+ module Pod
5
+ module Downloader
6
+ class <<self
7
+ alias_method :real_downloader_class_by_key, :downloader_class_by_key
8
+ end
9
+
10
+ def self.downloader_class_by_key
11
+ original = self.real_downloader_class_by_key
12
+ original[:nexus] = NexusDownloader
13
+ original
14
+ end
15
+
16
+ end
17
+ end
18
+
@@ -0,0 +1,256 @@
1
+ # require 'addressable'
2
+ require 'cocoapods-downloader'
3
+ require 'uri'
4
+ require 'net/http'
5
+ require 'json'
6
+
7
+ module Pod
8
+ module Downloader
9
+
10
+ class NexusDownloader < Base
11
+ def self.options
12
+ [:repo, :group, :artifact, :version, :type, :md5, :sha1,]
13
+ end
14
+
15
+ USER_AGENT_HEADER = 'User-Agent'.freeze
16
+
17
+ class UnsupportedFileTypeError < StandardError; end
18
+
19
+ private
20
+
21
+ executable :curl
22
+ # executable :mvn
23
+ executable :unzip
24
+ executable :tar
25
+ executable :hdiutil
26
+ # @return [String] the url of the remote source.
27
+ #
28
+ attr_accessor :filename, :download_path
29
+
30
+ def self.preprocess_options(options)
31
+
32
+ debug_puts "preprocess_options: #{options}"
33
+ artifact_item = self.request_artifact(options[:nexus], options)
34
+ debug_puts artifact_item
35
+ md5Val = artifact_item.checksum.md5
36
+
37
+ if options.key?(:md5)
38
+ raise "md5 value is not matched with remote file" unless options[:md5] == md5Val
39
+ else
40
+ options[:md5] = md5Val
41
+ end
42
+
43
+
44
+ # TODO: also check sha1
45
+ options
46
+ end
47
+
48
+ def self.request_artifact(url, options)
49
+
50
+ # https://stackoverflow.com/a/70596332/11884593
51
+ # http://192.168.138.192:8081/#admin/system/api
52
+ uri = URI("#{url}/service/rest/v1/search/assets")
53
+ params = {
54
+ 'sort' => 'version',
55
+ 'repository' => options[:repo],
56
+ 'maven.groupId' => options[:group],
57
+ 'maven.artifactId' => options[:artifact],
58
+ # maven don't allow '/' in version, so we replace it with '_' automatically
59
+ 'maven.baseVersion' => options[:version].gsub('/', '_'),
60
+ 'maven.extension' => options[:type],
61
+ 'prerelease' => false
62
+ }
63
+ uri.query = URI.encode_www_form(params)
64
+
65
+ debug_puts("uri: #{uri}")
66
+ res = Net::HTTP.get_response(uri)
67
+ raise DownloaderError, 'Search failed!' if res.is_a?(Net::HTTPError) || res.body.to_s.empty?
68
+ debug_puts "res.body: #{res.body.to_s}"
69
+
70
+ parsed_model = JSON.parse(res.body, object_class: OpenStruct)
71
+ raise DownloaderError, "Can't find matched artifact!" if parsed_model.items.empty?
72
+ debug_puts "aaa3: #{parsed_model.items.first}"
73
+ parsed_model.items.to_a.first
74
+
75
+ end
76
+
77
+ def download!
78
+ @filename = filename_with_type(type)
79
+ @download_path = target_path + @filename
80
+ download_file(@download_path)
81
+ verify_checksum(@download_path)
82
+ extract_with_type(@download_path, type)
83
+ end
84
+
85
+ def type
86
+ if options[:type]
87
+ options[:type].to_sym
88
+ else
89
+ type_with_url(url)
90
+ end
91
+ end
92
+
93
+ def headers
94
+ options[:headers]
95
+ end
96
+
97
+ # @note The archive is flattened if it contains only one folder and its
98
+ # extension is either `tgz`, `tar`, `tbz` or the options specify
99
+ # it.
100
+ #
101
+ # @return [Bool] Whether the archive should be flattened if it contains
102
+ # only one folder.
103
+ #
104
+ def should_flatten?
105
+ if options.key?(:flatten)
106
+ options[:flatten]
107
+ elsif %i[tgz tar tbz txz].include?(type)
108
+ true # those archives flatten by default
109
+ else
110
+ false # all others (actually only .zip) default not to flatten
111
+ end
112
+ end
113
+
114
+ def type_with_url(url)
115
+ case URI.parse(url).path
116
+ when /\.zip$/
117
+ :zip
118
+ when /\.(tgz|tar\.gz)$/
119
+ :tgz
120
+ when /\.tar$/
121
+ :tar
122
+ when /\.(tbz|tar\.bz2)$/
123
+ :tbz
124
+ when /\.(txz|tar\.xz)$/
125
+ :txz
126
+ when /\.dmg$/
127
+ :dmg
128
+ end
129
+ end
130
+
131
+ def filename_with_type(type = :zip)
132
+ case type
133
+ when :zip, :tgz, :tar, :tbz, :txz, :dmg
134
+ "file.#{type}"
135
+ else
136
+ raise UnsupportedFileTypeError, "Unsupported file type: #{type}"
137
+ end
138
+ end
139
+
140
+ def extract_with_type(full_filename, type = :zip)
141
+ unpack_from = full_filename
142
+ unpack_to = @target_path
143
+
144
+ case type
145
+ when :zip
146
+ unzip! unpack_from, '-d', unpack_to
147
+ when :tar, :tgz, :tbz, :txz
148
+ tar! 'xf', unpack_from, '-C', unpack_to
149
+ when :dmg
150
+ extract_dmg(unpack_from, unpack_to)
151
+ else
152
+ raise UnsupportedFileTypeError, "Unsupported file type: #{type}"
153
+ end
154
+
155
+ # If the archive is a tarball and it only contained a folder, move its
156
+ # contents to the target (#727)
157
+ #
158
+ if should_flatten?
159
+ contents = target_path.children
160
+ contents.delete(target_path + @filename)
161
+ entry = contents.first
162
+ if contents.count == 1 && entry.directory?
163
+ tmp_entry = entry.sub_ext("#{entry.extname}.tmp")
164
+ begin
165
+ FileUtils.move(entry, tmp_entry)
166
+ FileUtils.move(tmp_entry.children, target_path)
167
+ ensure
168
+ FileUtils.remove_entry(tmp_entry)
169
+ end
170
+ end
171
+ end
172
+
173
+ FileUtils.rm(unpack_from) if File.exist?(unpack_from)
174
+ end
175
+
176
+ def extract_dmg(unpack_from, unpack_to)
177
+ require 'rexml/document'
178
+ plist_s = hdiutil! 'attach', '-plist', '-nobrowse', unpack_from, '-mountrandom', unpack_to
179
+ plist = REXML::Document.new plist_s
180
+ xpath = '//key[.="mount-point"]/following-sibling::string'
181
+ mount_point = REXML::XPath.first(plist, xpath).text
182
+ FileUtils.cp_r(Dir.glob(mount_point + '/*'), unpack_to)
183
+ hdiutil! 'detach', mount_point
184
+ end
185
+
186
+ def compare_hash(filename, hasher, hash)
187
+ incremental_hash = hasher.new
188
+
189
+ File.open(filename, 'rb') do |file|
190
+ buf = ''
191
+ incremental_hash << buf while file.read(1024, buf)
192
+ end
193
+
194
+ computed_hash = incremental_hash.hexdigest
195
+
196
+ return unless computed_hash != hash
197
+
198
+ raise DownloaderError, 'Verification checksum was incorrect, ' \
199
+ "expected #{hash}, got #{computed_hash}"
200
+ end
201
+
202
+ # Verify that the downloaded file matches a sha1 hash
203
+ #
204
+ def verify_sha1_hash(filename, hash)
205
+ require 'digest/sha1'
206
+ compare_hash(filename, Digest::SHA1, hash)
207
+ end
208
+
209
+ # Verify that the downloaded file matches a sha256 hash
210
+ #
211
+ def verify_sha256_hash(filename, hash)
212
+ require 'digest/sha2'
213
+ compare_hash(filename, Digest::SHA2, hash)
214
+ end
215
+
216
+ # Verify that the downloaded file matches the hash if set
217
+ #
218
+ def verify_checksum(filename)
219
+ if options[:sha256]
220
+ verify_sha256_hash(filename, options[:sha256])
221
+ elsif options[:sha1]
222
+ verify_sha1_hash(filename, options[:sha1])
223
+ end
224
+ end
225
+
226
+ def download_file(download_path)
227
+ debug_puts "hl: download_file: #{download_path}"
228
+ artifact_item = NexusDownloader.request_artifact(url, options)
229
+ source_url = artifact_item.downloadUrl
230
+ parameters = ['-f', '-L', '-o', download_path, source_url, '--create-dirs', '--netrc-optional', '--retry', '2']
231
+ parameters << user_agent_argument if headers.nil? ||
232
+ headers.none? { |header| header.casecmp(USER_AGENT_HEADER).zero? }
233
+
234
+ unless headers.nil?
235
+ headers.each do |h|
236
+ parameters << '-H'
237
+ parameters << h
238
+ end
239
+ end
240
+
241
+ debug_puts "curl parameters: #{parameters}"
242
+ curl! parameters
243
+ end
244
+
245
+ # Returns a cURL command flag to add the CocoaPods User-Agent.
246
+ #
247
+ # @return [String] cURL command -A flag and User-Agent.
248
+ #
249
+ def user_agent_argument
250
+ debug_puts "1"
251
+ "-A '#{Http.user_agent_string}'"
252
+ end
253
+
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,23 @@
1
+ def debug_puts(content)
2
+ return unless CocoapodsNexusDownloader.debug
3
+
4
+ puts content
5
+ end
6
+
7
+ module CocoapodsNexusDownloader
8
+ class << self
9
+ # @return [Bool] the url of the remote source.
10
+ #
11
+ attr_accessor :debug
12
+
13
+ Pod::HooksManager.register('cocoapods-nexus-downloader', :pre_install) do |_context, options|
14
+ CocoapodsNexusDownloader.pre_install(options)
15
+ end
16
+
17
+ def pre_install(options)
18
+ debug_puts "pre_install hook: #{options}"
19
+ # Now we can configure the downloader to use the Azure CLI for downloading pods from the given hosts
20
+ @debug = options.fetch(:debug, false)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ require 'cocoapods-nexus-downloader/gem_version'
2
+ require 'cocoapods-nexus-downloader/pre-install'
3
+ require 'cocoapods-nexus-downloader/hook-cocoapods-downloader'
@@ -0,0 +1 @@
1
+ require 'cocoapods-nexus-downloader'
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-nexus-downloader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Hanley Lee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-01-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Host the pod's framework file on Nexus and download it using ':nexus'.
42
+ email:
43
+ - hanley.lei@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/cocoapods-nexus-downloader.rb
49
+ - lib/cocoapods-nexus-downloader/command.rb
50
+ - lib/cocoapods-nexus-downloader/command/nexus.rb
51
+ - lib/cocoapods-nexus-downloader/gem_version.rb
52
+ - lib/cocoapods-nexus-downloader/hook-cocoapods-downloader.rb
53
+ - lib/cocoapods-nexus-downloader/nexus-downloader.rb
54
+ - lib/cocoapods-nexus-downloader/pre-install.rb
55
+ - lib/cocoapods_plugin.rb
56
+ homepage: https://github.com/hanleylee/cocoapods-nexus-downloader
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubygems_version: 3.4.10
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: A CocoaPods plugin that enables referencing a pod using ':nexus' and downloading
79
+ it from Nexus in maven type.
80
+ test_files: []