cocoapods-nexus 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a7a9541ba6b2cab7847ca881391c0531d200a5ea17903d9688a3f5305685da3c
4
+ data.tar.gz: fe6507a84828877934b74c77e4935888b32c851a0af134e280c38dee879e79c7
5
+ SHA512:
6
+ metadata.gz: 530ea1d9c6eff91257c46d3dc52d9981841d147a728f22cfbd8b62b9ccb9e5258a80cb1a1c17511f9286836ba9652f149004a4f95bc92175436ea588133aa2ff
7
+ data.tar.gz: c36596c0e6471a86456178e8df7acdb98dd2c5103184fd2e9fcf9ea0edb6289b3a35a9396d029b2a9fa1086a08cceb26af31febe0093fe938ddc743e4fe34319
@@ -0,0 +1,13 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ tags:
5
+ - v*
6
+ jobs:
7
+ build:
8
+ runs-on: macos-latest
9
+ steps:
10
+ - name: Publish gem
11
+ uses: dawidd6/action-publish-gem@v1.1.0
12
+ with:
13
+ api_key: ${{secrets.RUBYGEMS_API_KEY}}
@@ -0,0 +1,56 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ # Ignore Byebug command history file.
17
+ .byebug_history
18
+
19
+ ## Specific to RubyMotion:
20
+ .dat*
21
+ .repl_history
22
+ build/
23
+ *.bridgesupport
24
+ build-iPhoneOS/
25
+ build-iPhoneSimulator/
26
+
27
+ ## Specific to RubyMotion (use of CocoaPods):
28
+ #
29
+ # We recommend against adding the Pods directory to your .gitignore. However
30
+ # you should judge for yourself, the pros and cons are mentioned at:
31
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
32
+ #
33
+ # vendor/Pods/
34
+
35
+ ## Documentation cache and generated files:
36
+ /.yardoc/
37
+ /_yardoc/
38
+ /doc/
39
+ /rdoc/
40
+
41
+ ## Environment normalization:
42
+ /.bundle/
43
+ /vendor/bundle
44
+ /lib/bundler/man/
45
+
46
+ # for a library or gem, you might want to ignore these files since the code is
47
+ # intended to run in multiple environments; otherwise, check them in:
48
+ # Gemfile.lock
49
+ # .ruby-version
50
+ # .ruby-gemset
51
+
52
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
+ .rvmrc
54
+
55
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
56
+ # .rubocop-https?--*
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'cocoapods'
7
+ gem 'cocoapods-core'
8
+ gem 'cocoapods-downloader'
9
+ gem 'claide'
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2020 mrdaios <mrdaios@gmail.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ # cocoapods-nexus
2
+
3
+ A description of cocoapods-nexus.
4
+
5
+ ## Installation
6
+
7
+ $ gem install cocoapods-nexus
8
+
9
+ ## Usage
10
+
11
+ $ pod spec nexus POD_NAME
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ def specs(dir)
4
+ FileList["spec/#{dir}/*_spec.rb"].shuffle.join(' ')
5
+ end
6
+
7
+ desc 'Runs all the specs'
8
+ task :specs do
9
+ sh "bundle exec bacon #{specs('**')}"
10
+ end
11
+
12
+ task :default => :specs
13
+
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'cocoapods-nexus'
7
+ spec.version = "0.0.1"
8
+ spec.authors = ['mrdaios']
9
+ spec.email = ['mrdaios@gmail.com']
10
+ spec.description = 'a cocoapods plugin for nexus.'
11
+ spec.summary = '运行时修改spec的source为nexus中的预编译的zip.'
12
+ spec.homepage = 'https://github.com/mrdaios/cocoapods-nexus'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ # spec.files = Dir['lib/**/*']
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_runtime_dependency 'cocoapods', '>= 1.9.3'
22
+ spec.add_runtime_dependency 'rest-client', '~> 2.1.0'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'rake', '~> 13.0'
26
+ end
@@ -0,0 +1,3 @@
1
+ require 'cocoapods-nexus/command'
2
+ require 'cocoapods-nexus/hook'
3
+ require 'cocoapods-nexus/nexus_source'
@@ -0,0 +1,16 @@
1
+ require 'cocoapods-nexus/api/connection'
2
+ require 'cocoapods-nexus/api/components'
3
+
4
+ module CocoapodsNexus
5
+ # https://github.com/Cisco-AMP/nexus_api
6
+ class API
7
+ attr_accessor :connection
8
+ attr_accessor :repo
9
+
10
+ # 用于管理nexus服务器
11
+ def initialize(hostname:, repo:)
12
+ @connection = CocoapodsNexus::API::NexusConnection.new(hostname: hostname)
13
+ @repo = repo
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ module CocoapodsNexus
2
+ class API
3
+ # 搜索组件
4
+ def search_maven_component(artifact_id:)
5
+ @connection.get_response(endpoint: "search?repository=#{@repo}&name=#{artifact_id}")
6
+ end
7
+
8
+ # 上传组件
9
+ def upload_maven_component(artifact_id:, version:, group_id:, podspec:, artifact:, files:)
10
+ parameters = {
11
+ 'maven2.artifactId' => artifact_id,
12
+ 'maven2.version' => version,
13
+ 'maven2.groupId' => group_id,
14
+ 'maven2.generate-pom' => true,
15
+ 'maven2.packaging' => artifact.nil? ? 'podspec' : File.extname(artifact).delete(".")
16
+ }
17
+ upload_files = []
18
+ upload_files << podspec unless podspec.nil?
19
+ upload_files << artifact unless artifact.nil?
20
+ upload_files | files unless files.nil?
21
+
22
+ upload_files.each_index do |index|
23
+ parameters["maven2.asset#{index + 1}"] = File.open(upload_files[index], 'r:utf-8')
24
+ parameters["maven2.asset#{index + 1}.extension"] = File.extname(upload_files[index]).delete(".")
25
+ end
26
+ @connection.post(endpoint: "components?repository=#{@repo}", parameters: parameters, headers: {})
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,158 @@
1
+ require 'base64'
2
+ require 'json'
3
+ require 'rest-client'
4
+ require 'uri'
5
+
6
+ module CocoapodsNexus
7
+ class API
8
+ class NexusConnection
9
+ VALID_RESPONSE_CODES = [200, 201, 204].freeze
10
+
11
+ attr_accessor :continuation_token
12
+
13
+ def initialize(hostname:)
14
+ @hostname = hostname
15
+ end
16
+
17
+ def get_response(endpoint:, paginate: false, headers: {'Content-Type' => 'application/json'}, api_version: 'v1')
18
+ response = send_get(endpoint, paginate, headers, api_version)
19
+ response.nil? ? {} : jsonize(response)
20
+ end
21
+
22
+ def get(endpoint:, paginate: false, headers: {'Content-Type' => 'application/json'}, api_version: 'v1')
23
+ valid?(send_get(endpoint, paginate, headers, api_version))
24
+ end
25
+
26
+ def post(endpoint:, parameters: '', headers: {'Content-Type' => 'application/json'}, api_version: 'v1')
27
+ response = send_request(
28
+ :post,
29
+ endpoint,
30
+ parameters: parameters,
31
+ headers: headers,
32
+ api_version: api_version
33
+ )
34
+ valid?(response)
35
+ end
36
+
37
+ def put(endpoint:, parameters: '', headers: {'Content-Type' => 'application/json'}, api_version: 'v1')
38
+ response = send_request(
39
+ :put,
40
+ endpoint,
41
+ parameters: parameters,
42
+ headers: headers,
43
+ api_version: api_version
44
+ )
45
+ valid?(response)
46
+ end
47
+
48
+ def delete(endpoint:, headers: {'Content-Type' => 'application/json'}, api_version: 'v1')
49
+ response = send_request(
50
+ :delete,
51
+ endpoint,
52
+ headers: headers,
53
+ api_version: api_version
54
+ )
55
+ valid?(response)
56
+ end
57
+
58
+ def head(asset_url:)
59
+ catch_connection_error do
60
+ RestClient.head(URI.escape(asset_url))
61
+ end
62
+ end
63
+
64
+ def content_length(asset_url:)
65
+ response = head(asset_url: asset_url)
66
+ return -1 unless response.respond_to?(:headers)
67
+ response.headers[:content_length]
68
+ end
69
+
70
+ def download(url:)
71
+ catch_connection_error do
72
+ RestClient.get(URI.escape(url), authorization_header)
73
+ end
74
+ end
75
+
76
+ def paginate?
77
+ !@continuation_token.nil?
78
+ end
79
+
80
+
81
+ private
82
+
83
+ def valid?(response)
84
+ return false if response.nil?
85
+ VALID_RESPONSE_CODES.include?(response.code) ? true : false
86
+ end
87
+
88
+ def handle(error)
89
+ puts 'ERROR: Request failed'
90
+ puts error
91
+ end
92
+
93
+ def catch_connection_error
94
+ begin
95
+ yield
96
+ rescue SocketError => error
97
+ return handle(error)
98
+ rescue RestClient::Unauthorized => error
99
+ return handle(error)
100
+ rescue RestClient::Exceptions::ReadTimeout => error
101
+ return handle(error)
102
+ rescue RestClient::ExceptionWithResponse => error
103
+ return handle(error.response)
104
+ rescue StandardError => error
105
+ return handle(error)
106
+ end
107
+ end
108
+
109
+ def authorization_header
110
+ {}
111
+ end
112
+
113
+ def send_request(connection_method, endpoint, parameters: '', headers: {}, api_version: 'v1')
114
+ parameters = parameters.to_json if headers['Content-Type'] == 'application/json'
115
+ url = "#{@hostname}/nexus/service/rest/#{api_version}/#{endpoint}"
116
+ catch_connection_error do
117
+ RestClient::Request.execute(
118
+ method: connection_method,
119
+ url: URI.escape(url),
120
+ payload: parameters,
121
+ headers: authorization_header.merge(headers)
122
+ )
123
+ end
124
+ end
125
+
126
+ def send_get(endpoint, paginate, headers, api_version)
127
+ url_marker = endpoint.include?('?') ? '&' : '?'
128
+ # paginate answers is the user requesting pagination, paginate? answers does a continuation token exist
129
+ # if an empty continuation token is included in the request we'll get an ArrayIndexOutOfBoundsException
130
+ endpoint += "#{url_marker}continuationToken=#{@continuation_token}" if paginate && paginate?
131
+ send_request(
132
+ :get,
133
+ endpoint,
134
+ headers: headers,
135
+ api_version: api_version
136
+ )
137
+ end
138
+
139
+ # That's right, nexus has inconsistent null values for its api
140
+ def continuation_token_for(json)
141
+ return nil if json['continuationToken'].nil?
142
+ return nil if json['continuationToken'] == 'nil'
143
+ json['continuationToken']
144
+ end
145
+
146
+ def jsonize(response)
147
+ json = JSON.parse(response.body)
148
+ if json.class == Hash
149
+ @continuation_token = continuation_token_for(json)
150
+ json = json['items'] if json['items']
151
+ end
152
+ json
153
+ rescue JSON::ParserError
154
+ response.body
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-nexus/command/nexus'
@@ -0,0 +1,24 @@
1
+ require 'cocoapods-nexus/nexus_source'
2
+
3
+ module Pod
4
+ class Command
5
+ class Nexus < Command
6
+ require 'cocoapods-nexus/command/nexus/add'
7
+ require 'cocoapods-nexus/command/nexus/list'
8
+ require 'cocoapods-nexus/command/nexus/push'
9
+
10
+ self.abstract_command = true
11
+
12
+ self.summary = 'a cocoapods plugin for nexus'
13
+
14
+ self.description = <<-DESC
15
+ a cocoapods plugin for nexus.
16
+ DESC
17
+
18
+ def initialize(argv)
19
+ @repos_nexus_dir = Pod::Config.instance.repos_dir
20
+ super
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,58 @@
1
+ require 'fileutils'
2
+
3
+ module Pod
4
+ class Command
5
+ class Nexus
6
+ class Add < Nexus
7
+ self.summary = 'Add a nexus repo.'
8
+
9
+ self.description = <<-DESC
10
+ 添加一个nexus的repo
11
+ DESC
12
+
13
+ self.arguments = [
14
+ CLAide::Argument.new('NAME', true),
15
+ CLAide::Argument.new('URL', true)
16
+ ]
17
+
18
+ def initialize(argv)
19
+ @name = argv.shift_argument
20
+ @url = argv.shift_argument
21
+ @silent = argv.flag?('silent', false)
22
+ @silent = false
23
+ super
24
+ end
25
+
26
+ def validate!
27
+ super
28
+ help! '需要配置`NAME`和`URL`.' unless @name && @url
29
+ end
30
+
31
+ def run
32
+ UI.section("从#{@url}添加#{@name}仓库") do
33
+ repos_path = File.join(@repos_nexus_dir, @name)
34
+ raise Pod::Informative.exception "#{repos_path}已经存在. 请删除或者执行'pod nexus add #{@name} #{@url}'" if File.exist?(repos_path) && !@silent
35
+ repo_dir_root = "#{@repos_nexus_dir}/#{@name}"
36
+
37
+ FileUtils.mkdir_p repo_dir_root
38
+
39
+ begin
40
+ nexus_path = create_nexus_file(repo_dir_root)
41
+ rescue StandardError => e
42
+ raise Informative, "Cannot create file '#{nexus_path}' because : #{e.message}."
43
+ end
44
+ UI.puts "Successfully added repo #{@name}".green unless @silent
45
+ end
46
+ end
47
+
48
+ def create_nexus_file(repo_dir_root)
49
+ nexus_path = "#{repo_dir_root}/.nexus"
50
+ nexus_path = File.new(nexus_path, 'wb')
51
+ nexus_path << @url
52
+ nexus_path.close
53
+ nexus_path
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,34 @@
1
+ require 'fileutils'
2
+ require 'cocoapods-nexus/nexus_source'
3
+
4
+ module Pod
5
+ class Command
6
+ class Nexus
7
+ class List < Nexus
8
+ self.summary = 'Add a nexus repo.'
9
+
10
+ self.description = <<-DESC
11
+ 添加一个nexus的repo
12
+ DESC
13
+
14
+ def run
15
+ repos_dir = Pod::Config.instance.repos_dir
16
+ dirs = Dir.glob "#{repos_dir}/*/"
17
+ repos = []
18
+ dirs.each do |dir|
19
+ next unless File.exist?("#{dir}/.nexus")
20
+ url = File.read("#{dir}/.nexus")
21
+ repos.push Pod::NexusSource.new(dir, url) if url
22
+ end
23
+
24
+ repos.each { |repo|
25
+ UI.title repo.name do
26
+ UI.puts "- URL: #{repo.url}"
27
+ UI.puts "- Path: #{repo.repo}"
28
+ end
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,71 @@
1
+ require 'cocoapods-nexus/api'
2
+
3
+ module Pod
4
+ class Command
5
+ class Nexus
6
+ class Push < Nexus
7
+ self.summary = 'Push a podspec.'
8
+
9
+ self.description = <<-DESC
10
+ Push a podspec to nexus.
11
+ DESC
12
+
13
+ self.arguments = [
14
+ CLAide::Argument.new('NAME.podspec', true)
15
+ ]
16
+
17
+ def self.options
18
+ [
19
+ ['--url=url', 'a nexus hostname'],
20
+ ['--repo=repo', 'a nexus repo'],
21
+ ['--artifact=artifact', 'a nexus artifact']
22
+ ].concat(super)
23
+ end
24
+
25
+ def initialize(argv)
26
+ @podspec = argv.shift_argument
27
+ @url = argv.option('url')
28
+ @repo = argv.option('repo')
29
+ @artifact = argv.option('artifact')
30
+ super
31
+ end
32
+
33
+ def validate!
34
+ super
35
+ help! 'A podspec is required.' unless @podspec && File.exist?(File.expand_path(@podspec))
36
+ help! 'A url is required.' unless @url
37
+ help! 'A repo is required.' unless @repo
38
+ end
39
+
40
+ def run
41
+ podspec_path = File.expand_path(@podspec)
42
+ artifact_path = File.expand_path(@artifact) unless @artifact.nil?
43
+
44
+ UI.section("开始发布 #{File.basename(@podspec)} -> #{@url}/nexus/#browse/browse:#{@repo}") do
45
+ spec = Specification.from_file(podspec_path)
46
+ artifact_id = spec.attributes_hash['name']
47
+ version = spec.attributes_hash['version']
48
+ group_id = 'Specs'
49
+
50
+ if nexus_api.upload_maven_component(artifact_id: artifact_id,
51
+ version: version,
52
+ group_id: group_id,
53
+ podspec: podspec_path,
54
+ artifact: artifact_path,
55
+ files: [])
56
+ UI.puts "成功发布 #{artifact_id}(#{version})"
57
+ else
58
+ raise Informative, "发布失败 #{artifact_id}(#{version}),请检查~/.netrc文件或#{@repo}类型"
59
+ end
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def nexus_api
66
+ @nexus_api ||= CocoapodsNexus::API.new(hostname: @url, repo: @repo)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,39 @@
1
+ require 'cocoapods-downloader/remote_file'
2
+
3
+ module Pod
4
+ module Downloader
5
+ class NexusHttp < RemoteFile
6
+ def self.options
7
+ [:type, :name]
8
+ end
9
+
10
+ private
11
+
12
+ executable :curl
13
+
14
+ def download!
15
+ @filename = "#{options[:name]}.#{'podspec'.to_sym}"
16
+ @download_path = @target_path + @filename
17
+ download_file(@download_path)
18
+ end
19
+
20
+ def download_file(full_filename)
21
+ parameters = ['-f', '-L', '-o', full_filename, url, '--create-dirs', '--netrc-optional', '--retry', '2']
22
+ parameters << user_agent_argument if headers.nil? ||
23
+ headers.none? { |header| header.casecmp(USER_AGENT_HEADER).zero? }
24
+ unless headers.nil?
25
+ headers.each do |h|
26
+ parameters << '-H'
27
+ parameters << h
28
+ end
29
+ end
30
+ # 通过curl下载文件
31
+ curl! parameters
32
+ end
33
+
34
+ def user_agent_argument
35
+ "-A '#{Http.user_agent_string}'"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,2 @@
1
+ require 'cocoapods-nexus/hook/analyzer'
2
+ require 'cocoapods-nexus/hook/manager'
@@ -0,0 +1,29 @@
1
+ # require 'cocoapods'
2
+ # require 'cocoapods-nexus/nexus_source'
3
+ #
4
+ # module Pod
5
+ # class Installer
6
+ # class Analyzer
7
+ # alias orig_sources sources
8
+ #
9
+ # # 修改pod的sources,用于注入cocoapods-nexus
10
+ # def sources
11
+ # value = orig_sources
12
+ # if podfile.sources.empty? && podfile.plugins.key?('cocoapods-nexus')
13
+ # sources = []
14
+ # plugin_config = podfile.plugins['cocoapods-nexus']
15
+ # # all sources declared in the plugin clause
16
+ # plugin_config['sources'].uniq.map do |config|
17
+ # name = config['name']
18
+ # url = config['url']
19
+ #
20
+ # sources.push(Pod::NexusSource.new("nexus_#{name}", url))
21
+ # end
22
+ # @sources = sources
23
+ # else
24
+ # orig_sources
25
+ # end
26
+ # end
27
+ # end
28
+ # end
29
+ # end
@@ -0,0 +1,49 @@
1
+ # require 'cocoapods-core'
2
+ # require 'cocoapods-nexus/api'
3
+
4
+ # module Pod
5
+ # class Installer
6
+ # alias_method :old_root_specs, :root_specs
7
+ # def root_specs
8
+ # # 通过修改specs的source到nexus下载zip(不完美的解决方案)
9
+ # specs = old_root_specs
10
+ # specs = specs.map{|spec| modify_spec_if_find_last_version(spec)}
11
+ # specs
12
+ # end
13
+
14
+ # private
15
+
16
+ # def modify_spec_if_find_last_version(spec)
17
+ # attributes_hash = spec.attributes_hash
18
+ # spec_name = attributes_hash['name']
19
+ # spec_version = attributes_hash['version']
20
+ # artifacte = nexus_find_artifacte(spec_name: spec_name, spec_version: spec_version)
21
+ # if artifacte != nil
22
+ # asset_zip = artifacte['assets'].select{ |asset| asset['path'].end_with?('zip') }.first
23
+ # if asset_zip != nil
24
+ # attributes_hash['source'] = {
25
+ # 'http' => asset_zip['downloadUrl']
26
+ # }
27
+ # puts "Downloading #{spec_name}(#{spec_version})from nexus(#{asset_zip['downloadUrl']})"
28
+ # spec.attributes_hash = attributes_hash
29
+ # end
30
+ # end
31
+ # spec
32
+ # end
33
+
34
+ # def nexus_find_artifacte(spec_name:, spec_version:)
35
+ # artifacte = {}
36
+ # api.each do |api|
37
+ # artifactes = api.search_maven_component(artifact_id: spec_name)
38
+ # artifacte = artifactes.select{ |artifacte| artifacte['version'].start_with?(spec_version) }.sort_by{ |artifacte| artifacte['version'].downcase }.last
39
+ # break if artifacte != nil
40
+ # end
41
+ # artifacte
42
+ # end
43
+
44
+ # def api
45
+ # nexus_options = Pod::Config.instance.podfile.get_options || []
46
+ # @apis = @apis || nexus_options.map{|nexus| CocoapodsNexus::API.new(hostname: nexus['endpoint'], repo: nexus['repo'])}
47
+ # end
48
+ # end
49
+ # end
@@ -0,0 +1,22 @@
1
+ require 'cocoapods'
2
+ require 'cocoapods-nexus/nexus_source'
3
+
4
+ module Pod
5
+ class Source
6
+ class Manager
7
+ alias orgin_source_from_path source_from_path
8
+
9
+ def source_from_path(path)
10
+ @new_sources_by_path ||= Hash.new do |hash, key|
11
+ nexus_file_path = File.join(key, ".nexus")
12
+ hash[key] = if File.exist?(nexus_file_path)
13
+ Pod::NexusSource.new(key, File.read(nexus_file_path))
14
+ else
15
+ orgin_source_from_path(key)
16
+ end
17
+ end
18
+ @new_sources_by_path[path]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,103 @@
1
+ require 'cocoapods-nexus/api'
2
+ require 'cocoapods-nexus/downloader'
3
+
4
+ module Pod
5
+ class NexusSource < Source
6
+ def initialize(repo, url)
7
+ @source_url = url
8
+ super(repo)
9
+ end
10
+
11
+ def url
12
+ if @source_url
13
+ @source_url.to_s
14
+ else
15
+ # after super(repo) repo is now the path to the repo
16
+ File.read("#{repo}/.nexus") if File.exist?("#{repo}/.nexus")
17
+ end
18
+ end
19
+
20
+ def git?
21
+ false
22
+ end
23
+
24
+ def type
25
+ 'nexus'
26
+ end
27
+
28
+ # 从nexus查询依赖
29
+ # @param [Object] query
30
+ def search(query)
31
+ unless File.exist?("#{repo}/.nexus")
32
+ raise Informative, "Unable to find a source named: `#{name}`"
33
+ end
34
+
35
+ found = find_local_podspec(query)
36
+ # 本地没查询到,则从nexus服务查询
37
+ if found == []
38
+ # 暂时这样处理
39
+ spec_version = query.requirement.requirements.last.last.to_s
40
+ artifacte = nexus_find_artifacte(spec_name: query.root_name, spec_version: spec_version)
41
+ if artifacte
42
+ download_url = parse_artifacte_asset_url(artifacte, 'podspec')
43
+ if download_url
44
+ target_path = "#{@repo}/#{query.root_name}/#{spec_version}"
45
+ downloader = Pod::Downloader::NexusHttp.new(target_path, download_url, {:type => 'podspec', :name => query.root_name})
46
+ downloader.download
47
+
48
+ found = find_local_podspec(query)
49
+ end
50
+ end
51
+ end
52
+
53
+ if found == [query.root_name]
54
+ set = set(query.root_name)
55
+ set if set.specification_name == query.root_name
56
+ end
57
+ end
58
+
59
+ def specification(name, version)
60
+ specification = super
61
+ version = version.version if version.is_a?(Pod::Version)
62
+ artifacte = nexus_find_artifacte(spec_name: name, spec_version: version)
63
+ download_url = parse_artifacte_asset_url(artifacte, 'zip')
64
+ if download_url
65
+ specification.attributes_hash['source'] = {
66
+ 'http' => download_url
67
+ }
68
+ specification.attributes_hash['vendored_frameworks'] = "#{name}.framework"
69
+ end
70
+ specification
71
+ end
72
+
73
+ private
74
+
75
+ # 从本地repo查询spec
76
+ def find_local_podspec(query)
77
+ query = query.root_name if query.is_a?(Dependency)
78
+ found = []
79
+ Pathname.glob(pod_path(query)) do |path|
80
+ next unless Dir.foreach(path).any? { |child| child != '.' && child != '..' }
81
+ found << path.basename.to_s
82
+ end
83
+ found
84
+ end
85
+
86
+ # 解析附件downloadUrl
87
+ def parse_artifacte_asset_url(artifacte, asset_type)
88
+ asset = artifacte['assets'].select { |asset| asset['path'].end_with?(asset_type) }.first
89
+ asset['downloadUrl'] unless asset['downloadUrl'].nil?
90
+ end
91
+
92
+ def nexus_find_artifacte(spec_name:, spec_version:)
93
+ artifactes = nexus_api.search_maven_component(artifact_id: spec_name)
94
+ artifacte = artifactes.select { |artifacte| artifacte['version'].start_with?(spec_version) }.sort_by { |artifacte| artifacte['version'].downcase }.last
95
+ artifacte
96
+ end
97
+
98
+ def nexus_api
99
+ repo_name = File.basename(@repo).gsub('nexus_', '')
100
+ @nexus_api ||= CocoapodsNexus::API.new(hostname: url, repo: repo_name)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,29 @@
1
+ require 'cocoapods'
2
+ require 'cocoapods-nexus'
3
+
4
+ Pod::HooksManager.register('cocoapods-nexus', :source_provider) do |context, options|
5
+ Pod::UI.message 'cocoapods-nexus received source_provider hook'
6
+ unless (sources = options['sources'])
7
+ raise Pod::Informative.exception 'cocoapods-nexus插件需要配置sources参数.'
8
+ end
9
+
10
+ sources.each do |source_config|
11
+ name = source_config['name']
12
+ url = source_config['url']
13
+ source = Pod::NexusSource.new(File.join(Pod::Config.instance.repos_dir, name), url)
14
+ update_or_add_source(source)
15
+ context.add_source(source)
16
+ end
17
+ end
18
+
19
+ def update_or_add_source(source)
20
+ name = source.name
21
+ url = source.url
22
+ dir = source.repo
23
+
24
+ unless dir.exist?
25
+ argv = CLAide::ARGV.new([name, url])
26
+ cmd = Pod::Command::Nexus::Add.new(argv)
27
+ cmd.run
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe Command::Nexus do
5
+ describe 'CLAide' do
6
+ it 'registers it self' do
7
+ Command.parse(%w{ nexus }).should.be.instance_of Command::Nexus
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,50 @@
1
+ require 'pathname'
2
+ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
3
+ $:.unshift((ROOT + 'lib').to_s)
4
+ $:.unshift((ROOT + 'spec').to_s)
5
+
6
+ require 'bundler/setup'
7
+ require 'bacon'
8
+ require 'mocha-on-bacon'
9
+ require 'pretty_bacon'
10
+ require 'pathname'
11
+ require 'cocoapods'
12
+
13
+ Mocha::Configuration.prevent(:stubbing_non_existent_method)
14
+
15
+ require 'cocoapods_plugin'
16
+
17
+ #-----------------------------------------------------------------------------#
18
+
19
+ module Pod
20
+
21
+ # Disable the wrapping so the output is deterministic in the tests.
22
+ #
23
+ UI.disable_wrap = true
24
+
25
+ # Redirects the messages to an internal store.
26
+ #
27
+ module UI
28
+ @output = ''
29
+ @warnings = ''
30
+
31
+ class << self
32
+ attr_accessor :output
33
+ attr_accessor :warnings
34
+
35
+ def puts(message = '')
36
+ @output << "#{message}\n"
37
+ end
38
+
39
+ def warn(message = '', actions = [])
40
+ @warnings << "#{message}\n"
41
+ end
42
+
43
+ def print(message)
44
+ @output << message
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ #-----------------------------------------------------------------------------#
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-nexus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - mrdaios
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-09-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cocoapods
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.9.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.9.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ description: a cocoapods plugin for nexus.
70
+ email:
71
+ - mrdaios@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".github/workflows/main.yml"
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.md
81
+ - Rakefile
82
+ - cocoapods-nexus.gemspec
83
+ - lib/cocoapods-nexus.rb
84
+ - lib/cocoapods-nexus/api.rb
85
+ - lib/cocoapods-nexus/api/components.rb
86
+ - lib/cocoapods-nexus/api/connection.rb
87
+ - lib/cocoapods-nexus/command.rb
88
+ - lib/cocoapods-nexus/command/nexus.rb
89
+ - lib/cocoapods-nexus/command/nexus/add.rb
90
+ - lib/cocoapods-nexus/command/nexus/list.rb
91
+ - lib/cocoapods-nexus/command/nexus/push.rb
92
+ - lib/cocoapods-nexus/downloader.rb
93
+ - lib/cocoapods-nexus/hook.rb
94
+ - lib/cocoapods-nexus/hook/analyzer.rb
95
+ - lib/cocoapods-nexus/hook/installer.rb
96
+ - lib/cocoapods-nexus/hook/manager.rb
97
+ - lib/cocoapods-nexus/nexus_source.rb
98
+ - lib/cocoapods_plugin.rb
99
+ - spec/command/nexus_spec.rb
100
+ - spec/spec_helper.rb
101
+ homepage: https://github.com/mrdaios/cocoapods-nexus
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubygems_version: 3.0.3
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: 运行时修改spec的source为nexus中的预编译的zip.
124
+ test_files:
125
+ - spec/command/nexus_spec.rb
126
+ - spec/spec_helper.rb