Class: Composer::Package::Loader::HashLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/composer/package/loader/hash_loader.rb

Overview

Loads a package from a hash

PHP Authors: Konstantin Kudryashiv <[email protected]> Jordi Boggiano <[email protected]>

Ruby Authors: Ioannis Kappas <[email protected]>

Instance Method Summary collapse

Constructor Details

#initialize(parser = nil, load_options = false) ⇒ HashLoader

Returns a new instance of HashLoader.



24
25
26
27
28
# File 'lib/composer/package/loader/hash_loader.rb', line 24

def initialize(parser = nil, load_options = false)
  parser = Composer::Package::Version::VersionParser.new unless parser
  @version_parser = parser
  @load_options = load_options
end

Instance Method Details

#get_branch_alias(config) ⇒ Object

Retrieves a branch alias (dev-master => 1.0.x-dev for example) if it exists

Params: config array The entire package config

Returns: string|nil normalized version of the branch alias or null if there is none



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/composer/package/loader/hash_loader.rb', line 275

def get_branch_alias(config)
  return nil unless
    (config['version'].start_with?('dev-') || config['version'].end_with?('-dev')) &&
    config.key?('extra') &&
    config['extra'].key?('branch-alias') &&
    config['extra']['branch-alias'].is_a?(Hash)

  config['extra']['branch-alias'].each do |source_branch, target_branch|
    # ensure it is an alias to a -dev package
    next if !target_branch.end_with?('-dev')

    # normalize without -dev and ensure it's a numeric branch that is parseable
    validated_target_branch = @version_parser.normalize_branch(target_branch[0..-5])
    next if !validated_target_branch.end_with?('-dev')

    # ensure that it is the current branch aliasing itself
    next if config['version'].downcase != source_branch.downcase

    # If using numeric aliases ensure the alias is a valid subversion
    source_prefix = @version_parser.parse_numeric_alias_prefix(source_branch)
    target_prefix = @version_parser.parse_numeric_alias_prefix(target_branch)
    next if source_prefix && target_prefix && target_prefix.index(source_prefix) != 0 #(stripos($targetPrefix, $sourcePrefix) !== 0)

    return validated_target_branch
  end
  nil
end

#load(config, class_name = 'Composer::Package::CompletePackage') ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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
155
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/composer/package/loader/hash_loader.rb', line 30

def load(config, class_name = 'Composer::Package::CompletePackage')
  unless config
    raise ArgumentError,
          'Invalid package configuration supplied.'
  end

  unless config.key?('name')
    raise UnexpectedValueError,
          "Unknown package has no name defined (#{config.to_json})."
  end

  unless config.key?('version')
    raise UnexpectedValueError,
          "Package #{config['name']} has no version defined."
  end

  # handle already normalized versions
  if config.key?('version_normalized')
    version = config['version_normalized']
  else
    version = @version_parser.normalize(config['version'])
  end

  package = Object.const_get(class_name).new(
    config['name'],
    version,
    config['version']
  )

  # parse type
  if config.key?('type')
    package.type = config['type'].downcase
  else
    package.type = 'library'
  end

  # parse target-dir
  if config.key?('target-dir')
    package.target_dir = config['target-dir']
  end

  # parse extra
  if config.key?('extra') && config['extra'].is_a?(Hash)
    package.extra = config['extra']
  end

  # parse bin
  if config.key?('bin')
    unless config['bin'].is_a?(Array)
      raise UnexpectedValueError,
            "Package #{config['name']}'s bin key should be an hash, \
            #{config['bin'].class.name} given."
    end
    config['bin'].each do |bin|
      bin.gsub!(/^\/+/, '')
    end
    package.binaries = config['bin']
  end

  # parse installation source
  if config.key?('installation-source')
    package.installation_source = config['installation-source']
  end

  # parse source
  if config.key?('source')
    if [:type, :url, :reference].all? {|k| config['source'].key? k}
      raise UnexpectedValueError,
            "Package #{config['name']}'s source key should be \
            specified as \
            {\"type\": ..., \"url\": ..., \"reference\": ...}, \n
            #{config['source'].to_json} given."
    end
    package.source_type = config['source']['type']
    package.source_url = config['source']['url']
    package.source_reference = config['source']['reference']
    if config['source'].key?('mirrors')
      package.source_mirrors = config['source']['mirrors']
    end
  end

  #parse dist
  if config.key?('dist')
    if [:type, :url].all? {|k| config['dist'].key? k}
      raise UnexpectedValueError,
            "Package #{config['name']}'s dist key should be \
            specified as \
            {\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...},\n
            #{config['dist'].to_json} given."
    end
    package.dist_type = config['dist']['type']
    package.dist_url = config['dist']['url']

    package.dist_reference = config['dist'].key?('reference') ?
                              config['dist']['reference'] : nil

    package.dist_sha1_checksum = config['dist'].key?('shasum') ?
                              config['dist']['shasum'] : nil

    if config['dist'].key?('mirrors')
      package.dist_mirrors = config['dist']['mirrors']
    end
  end

  # parse supported link types
  Composer::Package::BasePackage::SUPPORTED_LINK_TYPES.each do |type, opts|
    next if !config.key?(type)
    package.send(
      "#{opts['method']}=",
      @version_parser.parse_links(
        package.name,
        package.pretty_version,
        opts['description'],
        config[type]
      )
    )
  end

  # parse suggest
  if config.key?('suggest') && config['suggest'].is_a?(Hash)
    config['suggest'].each do |target, reason|
      if 'self.version' === reason.strip!
        config['suggest'][target] = package.pretty_version
      end
    end
    package.suggests = config['suggest']
  end

  # parse autoload
  if config.key? 'autoload'
    package.autoload = config['autoload']
  end

  # parse autoload-dev
  if config.key? 'autoload-dev'
    package.dev_autoload = config['autoload-dev']
  end

  # parse include-path
  if config.key? 'include-path'
    package.include_paths = config['include-path']
  end

  # parse time
  if !is_empty?(config, 'time')
    time = is_numeric?(config['time']) ? "@#{config['time']}" : config['time']
    begin
      date = Time.zone.parse(time)
      package.release_date = date
    rescue Exception => e
      log("Time Exception #{e}")
    end
  end

  # parse notification url
  if !is_empty?(config, 'notification-url')
    package.notification_url = config['notification-url']
  end

  # parse archive excludes
  if config.key?('archive') &&
     config['archive'].key?('exclude') &&
     !config['archive']['exclude'].empty?
    package.archive_excludes = config['archive']['exclude']
  end

  if package.instance_of?(Composer::Package::CompletePackage)

    # parse scripts
    if config.key?('scripts') && config['scripts'].is_a?(Array)
      config['scripts'].each do |event, listeners|
        config['scripts'][event] = Array(listeners)
      end
      package.scripts = config['scripts']
    end

    # parse description
    if !is_empty?(config, 'description') && config['description'].is_a?(String)
      package.description = config['description']
    end

    # parse homepage
    if !is_empty?(config, 'homepage') && config['homepage'].is_a?(String)
      package.homepage = config['homepage']
    end

    # parse keywords
    if !is_empty?(config, 'keywords') && config['keywords'].is_a?(Array)
      package.keywords = config['keywords']
    end

    # parse license
    if !is_empty?(config, 'license')
      package.license = config['license'].is_a?(Array) ? config['license'] : [config['license']]
    end

    # parse authors
    if !is_empty?(config, 'authors') && config['authors'].is_a?(Array)
      package.authors = config['authors']
    end

    # parse support
    if config.key?('support')
      package.support = config['support']
    end

    # parse abandoned
    if config.key?('abandoned')
      package.abandoned = config['abandoned']
    end

  end

  if alias_normalized = get_branch_alias(config)
    if package.instance_of?(Composer::Package::RootPackage)
      package = Composer::Package::RootAliasPackage.new(
        package,
        alias_normalized,
        alias_normalized.gsub(/(\.9{7})+/, '.x')
      )
    else
      package = Composer::Package::AliasPackage.new(
        package,
        alias_normalized,
        alias_normalized.gsub(/(\.9{7})+/, '.x')
      )
    end
  end

  if @load_options && config.key?('transport-options')
    package.transport_options = config['transport-options']
  end

  package
end