Class: Pod::CodingArSource

Inherits:
Source
  • Object
show all
Defined in:
lib/coding_ar_source.rb

Instance Method Summary collapse

Constructor Details

#initialize(repo) ⇒ CodingArSource

Returns a new instance of CodingArSource.



3
4
5
# File 'lib/coding_ar_source.rb', line 3

def initialize(repo)
  super(repo)
end

Instance Method Details

#all_specsObject

Raises:

  • (Informative)


57
58
59
# File 'lib/coding_ar_source.rb', line 57

def all_specs
  raise Informative, "Can't retrieve all the specs for a CODING-AR-backed source."
end

#git?Boolean

Returns:

  • (Boolean)


202
203
204
# File 'lib/coding_ar_source.rb', line 202

def git?
  false
end

#handle_spec_response(response, req, changed_spec_paths, show_output) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/coding_ar_source.rb', line 156

def handle_spec_response(response, req, changed_spec_paths, show_output)
  file = req[:file]
  spec_name = req[:spec_name]
  spec_version = req[:spec_version]
  origin_content = req[:origin_content]

  UI.puts "- Fetch #{req[:url]}" if show_output

  if response.code == 0
    UI.puts "- Skipping #{spec_name} #{spec_version}: #{response.return_message}".yellow if show_output
    return
  elsif response.code != 200
    error_msg = response.body.to_s
    if error_msg.include?('Spec not found') || error_msg.include?('not found')
      UI.puts "- Skipping #{spec_name} #{spec_version}: Spec not found".yellow if show_output
    elsif error_msg.include?('URL using bad/illegal format') || error_msg.include?('missing URL')
      UI.puts "- Skipping #{spec_name} #{spec_version}: Invalid URL format".yellow if show_output
    else
      UI.puts "- Skipping #{spec_name} #{spec_version}: HTTP #{response.code}".yellow if show_output
    end
    return
  end

  begin
    latest_content = response.body
    if latest_content.to_s.start_with?('Pod not found')
      FileUtils.rm_rf(File.dirname(file))
      return
    end

    JSON.parse(latest_content)
    FileUtils.mkdir_p(File.dirname(file))
    File.open(file, 'wb') { |f| f << latest_content }

    changed_spec_paths.push(file) if origin_content != latest_content
  rescue JSON::ParserError => e
    UI.puts "- Skipping #{spec_name} #{spec_version}: Invalid JSON in response".yellow if show_output
  rescue => e
    UI.puts "- Skipping #{spec_name} #{spec_version}: #{e.message}".yellow if show_output
  end
end

#indexable?Boolean

Returns:

  • (Boolean)


206
207
208
# File 'lib/coding_ar_source.rb', line 206

def indexable?
  false
end

#nameObject



7
8
9
# File 'lib/coding_ar_source.rb', line 7

def name
  repo.basename.to_s
end

#pod_path(name) ⇒ Object



23
24
25
# File 'lib/coding_ar_source.rb', line 23

def pod_path(name)
  specs_dir.join(name)
end

#pod_setsObject

Raises:

  • (Informative)


61
62
63
# File 'lib/coding_ar_source.rb', line 61

def pod_sets
  raise Informative, "Can't retrieve all the pod sets for a CODING-AR-backed source."
end

#podsObject

Raises:

  • (Informative)


27
28
29
# File 'lib/coding_ar_source.rb', line 27

def pods
  raise Informative, "Can't retrieve all the pods for a CODING-AR-backed source."
end

#search(query) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/coding_ar_source.rb', line 65

def search(query)
  unless specs_dir
    raise Informative, "Unable to find a source named: `#{name}`"
  end
  if query.is_a?(Dependency)
    query = query.root_name
  end

  begin
    versions = list_version(query)
    if versions.class == Array and versions.length > 0
      set = set(query)
      set if set.specification_name == query
    end
  rescue RuntimeError => e
    if e.message.include?('not found')
      return nil
    else
      raise e
    end
  end
end

#search_by_name(query, full_text_search = false) ⇒ Object

Raises:

  • (Informative)


88
89
90
# File 'lib/coding_ar_source.rb', line 88

def search_by_name(query, full_text_search = false)
  raise Informative, "Can't search a CODING-AR-backed source by name."
end

#specification_path(name, version) ⇒ Object

Raises:

  • (ArgumentError)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/coding_ar_source.rb', line 40

def specification_path(name, version)
  raise ArgumentError, 'No name' unless name
  raise ArgumentError, 'No version' unless version
  unless versions(name).include?(Version.new(version))
    raise StandardError, "Unable to find the specification #{name} " \
      "(#{version}) in the #{self.name} source."
  end

  spec_url = "#{url}/Specs/#{name}/#{version.to_s}/#{name}.podspec.json"
  spec_path = File.join(specs_dir, name, version.to_s, "#{name}.podspec.json")
  FileUtils.mkdir_p File.dirname(spec_path)
  require 'coding_ar_util'
  CodingArUtil.download(spec_url, spec_path)

  spec_path
end

#specs_dirObject



19
20
21
# File 'lib/coding_ar_source.rb', line 19

def specs_dir
  repo
end

#typeObject



15
16
17
# File 'lib/coding_ar_source.rb', line 15

def type
  'CODING-AR'
end

#update(_show_output) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/coding_ar_source.rb', line 92

def update(_show_output)
  require 'json'
  require 'coding_ar_util'
  require 'typhoeus'
  require 'etc'

  changed_spec_paths = []
  UI.puts "Updating CODING-AR-backed repo #{name}".yellow if _show_output

  files = Pathname.glob(repo.join('**/*/*.json'))
  spec_requests = []

  files.each do |f|
    begin
      origin_content = File.read(f)
      spec = JSON.parse(origin_content)
      spec_url = "#{url}/Specs/#{spec['name']}/#{spec['version']}/#{spec['name']}.podspec.json"
      spec_requests << {
        file: f,
        url: spec_url,
        origin_content: origin_content,
        spec_name: spec['name'],
        spec_version: spec['version']
      }
    rescue JSON::ParserError => e
      UI.puts "- Skipping #{f}: Invalid JSON format".yellow if _show_output
    rescue => e
      UI.puts "- Skipping #{f}: #{e.message}".yellow if _show_output
    end
  end

  return [] if spec_requests.empty?

  max_concurrency = [[Etc.nprocessors * 2, 4].max, 20].min
  UI.puts "Fetching #{spec_requests.size} specs with #{max_concurrency} concurrent connections...".yellow if _show_output

  start_time = Time.now
  hydra = Typhoeus::Hydra.new(max_concurrency: max_concurrency)

  spec_requests.each do |req|
    request = Typhoeus::Request.new(
      req[:url],
      method: :get,
      netrc: :optional,
      netrc_file: ENV[CodingArUtil::CODING_AR_NETRC_PATH_ENV] || Netrc.default_path,
      followlocation: true,
      headers: { 'User-Agent' => CodingArUtil::USER_AGENT }
    )

    request.on_complete do |response|
      handle_spec_response(response, req, changed_spec_paths, _show_output)
    end

    hydra.queue(request)
  end

  hydra.run
  elapsed = Time.now - start_time

  UI.puts "Fetched #{spec_requests.size} specs in #{elapsed.round(2)}s (#{(spec_requests.size / elapsed).round(1)} specs/sec)".green if _show_output
  UI.puts "Successfully update CODING-AR-backed repo #{name}".green if _show_output
  []
end

#updateable?Boolean

Returns:

  • (Boolean)


198
199
200
# File 'lib/coding_ar_source.rb', line 198

def updateable?
  true
end

#urlObject



11
12
13
# File 'lib/coding_ar_source.rb', line 11

def url
  @url ||= File.read(repo.join('.coding_ar_url')).chomp.chomp('/')
end

#versions(name) ⇒ Object

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
38
# File 'lib/coding_ar_source.rb', line 31

def versions(name)
  eturn nil unless specs_dir
  raise ArgumentError, 'No name' unless name

  list_version(name).map do |v| 
    Version.new(v)
  end.compact.sort.reverse
end