Class: OTRS::SOPM

Inherits:
Object
  • Object
show all
Defined in:
lib/otrs/sopm.rb,
lib/otrs/sopm/version.rb

Overview

Contains just the version number, bundler / gem default design

Constant Summary collapse

VERSION =
'0.1.4'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sopm_file) ⇒ SOPM, Hash

Creates an instance based on a given SOPM file path.

Parameters:

  • sopm_file (String)

    the path to the SOPM file.



17
18
19
20
21
22
23
24
25
26
# File 'lib/otrs/sopm.rb', line 17

def initialize(sopm_file)

  @sopm_file = sopm_file

  sopm_read_handle = File.open(@sopm_file)
  @sopm            = Nokogiri::XML(sopm_read_handle)
  sopm_read_handle.close

  parse
end

Instance Attribute Details

#sopmObject (readonly)

Returns the value of attribute sopm.



10
11
12
# File 'lib/otrs/sopm.rb', line 10

def sopm
  @sopm
end

#structureObject (readonly)

Returns the value of attribute structure.



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

def structure
  @structure
end

Instance Method Details

#add_build_information(build_host) ⇒ Hash

Adds the buildhost and builddate to the SOPM file.

Parameters:

  • build_host (String)

    build host on which the OPM file was created.

Returns:

  • (Hash)

    the parsed SOPM structure.



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
# File 'lib/otrs/sopm.rb', line 103

def add_build_information(build_host)
  fail ArgumentError, 'Build_host has to be a string' unless build_host.is_a? String

  # add BuildHost
  if @sopm.xpath('/otrs_package/BuildHost').children.length == 0

    new_build_host_entry                                 = Nokogiri::XML::Node.new 'BuildHost', sopm
    new_build_host_entry.content                         = build_host
    @sopm.xpath('/otrs_package/Filelist').first.previous = new_build_host_entry.to_xml + "\n    "
  else
    @sopm.xpath('/otrs_package/BuildHost').children[0].content = build_host
  end

  # add BuildDate
  if @sopm.xpath('/otrs_package/BuildDate').children.length == 0

    new_build_date_entry                                 = Nokogiri::XML::Node.new 'BuildDate', sopm
    new_build_date_entry.content                         = Time.zone.now
    @sopm.xpath('/otrs_package/Filelist').first.previous = new_build_date_entry.to_xml + "\n    "
  else
    @sopm.xpath('/otrs_package/BuildDate').children[0].content = Time.zone.now
  end

  store
end

#add_file(location, permission = 660) ⇒ Hash

Adds a new file to the filelist of the SOPM file.

Parameters:

  • location (String)

    the file location.

  • permission (Integer) (defaults to: 660)

    the permissions with which the files should get created.

Returns:

  • (Hash)

    the parsed SOPM structure.



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
# File 'lib/otrs/sopm.rb', line 134

def add_file( location, permission = 660 )

  files_nodes = @sopm.xpath('/otrs_package/Filelist/File')

  update = true
  files_nodes.each { |files_node|

    next if files_node['Location'] != location
    next if files_node['Permission'] != permission

    update = false

    break
  }

  return if !update

  # append Filelist/File
  new_file_entry               = Nokogiri::XML::Node.new 'File', sopm
  new_file_entry['Permission'] = permission
  new_file_entry['Location']   = location

  files_nodes.last.next = "\n        " + new_file_entry.to_xml

  store
end

#opmString

Creates an OPM string out of the SOPM file.

Returns:

  • (String)

    OPM XML content with Base64 encoded files.



402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/otrs/sopm.rb', line 402

def opm

  opm = @sopm

  folder = File.dirname(@sopm_file)

  files_nodes = opm.xpath('/otrs_package/Filelist/File')
  files_nodes.each { |files_node|

    file_location = files_node['Location']
    file          = File.open("#{folder}/#{file_location}", 'r')
    file_content  = file.read
    file.close

    files_node['Encode'] = 'Base64'
    files_node.content   = Base64.strict_encode64( file_content )
  }

  opm.to_xml
end

#parseHash

Parses the given SOPM file.

Returns:

  • (Hash)

    the parsed SOPM structure.



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
265
266
267
268
269
270
271
272
273
274
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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/otrs/sopm.rb', line 176

def parse

  @structure = {}

  # Name
  @structure['name'] = @sopm.xpath('/otrs_package/Name').children[0].content

  # Version
  @structure['version'] = @sopm.xpath('/otrs_package/Version').children[0].content

  # Vendor
  @structure['vendor'] = @sopm.xpath('/otrs_package/Vendor').children[0].content

  # License
  @structure['license'] = @sopm.xpath('/otrs_package/License').children[0].content

  # URL
  # TODO: Remove! URL should be required
  if @sopm.xpath('/otrs_package/URL').children.length > 0
    @structure['url'] = @sopm.xpath('/otrs_package/URL').children[0].content
  end

  # BuildDate
  if @sopm.xpath('/otrs_package/BuildDate').children.length > 0
    @structure['build_date'] = @sopm.xpath('/otrs_package/BuildDate').children[0].content
  end

  # BuildHost
  if @sopm.xpath('/otrs_package/BuildHost').children.length > 0
    @structure['build_host'] = @sopm.xpath('/otrs_package/BuildHost').children[0].content
  end

  # PackageIs* blocks (optional)
  %w(Visible Downloadable Removable).each { |is_type|

    next if @sopm.xpath('/otrs_package/PackageIs' + is_type).children.length == 0

    flag = @sopm.xpath('/otrs_package/PackageIs' + is_type).children[0].content

    is_type.downcase!

    @structure['package_is_' + is_type] = flag == '1' ? true : false
  }

  # ChangeLog (optional)
  change_log_nodes = @sopm.xpath('/otrs_package/ChangeLog')
  if change_log_nodes.length > 0
    @structure['change_log'] = []
    change_log_nodes.each { |change_log_node|

      change_log_entry            = {}
      change_log_entry['version'] = change_log_node['Version']
      change_log_entry['date']    = change_log_node['Date']
      change_log_entry['log']     = change_log_node.children[0].content

      @structure['change_log'].push change_log_entry
    }
  end

  # OS (optional)
  os_nodes = @sopm.xpath('/otrs_package/OS')
  if os_nodes.length > 0
    @structure['os'] = []
    os_nodes.each { |os_node|

      @structure['os'].push os_node.children[0].content
    }
  end

  # Framework
  @structure['framework'] = []
  framework_nodes = @sopm.xpath('/otrs_package/Framework')
  framework_nodes.each { |framework_node|
    @structure['framework'].push framework_node.children[0].content
  }

  # PackageRequired (optional)
  package_required_nodes = @sopm.xpath('/otrs_package/PackageRequired')
  if package_required_nodes.length > 0
    @structure['package_required'] = []
    package_required_nodes.each { |package_required_node|

      package_required_entry            = {}
      package_required_entry['version'] = package_required_node['Version']
      package_required_entry['name']    = package_required_node.children[0].content

      @structure['package_required'].push package_required_entry
    }
  end

  # ModuleRequired (optional)
  module_required_nodes = @sopm.xpath('/otrs_package/ModuleRequired')
  if module_required_nodes.length > 0
    @structure['module_required'] = []
    module_required_nodes.each { |module_required_node|

      module_required_entry            = {}
      module_required_entry['version'] = module_required_node['Version']
      module_required_entry['name']    = module_required_node.children[0].content

      @structure['module_required'].push module_required_entry
    }
  end

  # Description
  @structure['description'] = []
  description_nodes = @sopm.xpath('/otrs_package/Description')
  description_nodes.each { |description_node|

    description_entry             = {}
    description_entry['language'] = description_node['Lang']
    description_entry['text']     = description_node.children[0].content

    @structure['description'].push description_entry
  }

  # Filelist/File
  @structure['files'] = []
  files_nodes = @sopm.xpath('/otrs_package/Filelist/File')
  files_nodes.each { |files_node|

    files_entry               = {}
    files_entry['permission'] = files_node['Permission']
    files_entry['location']   = files_node['Location']

    if files_node['Encode'] == 'Base64'
      files_entry['content'] = Base64.decode64( files_node.children[0].content )
    end

    @structure['files'].push files_entry
  }

  # Code blocks (optional)
  %w(Install Upgrade Reinstall Uninstall).each { |block_type|

    code_block_nodes = @sopm.xpath('/otrs_package/Code' + block_type)

    next if code_block_nodes.length == 0

    # convert to lowercase
    block_type.downcase!

    @structure[ 'code_' + block_type ] = []
    code_block_nodes.each { |code_block_node|

      code_block_entry         = {}
      code_block_entry['type'] = code_block_node['Type']
      code_block_entry['code'] = code_block_node.children[0].content

      # optional
      if code_block_node['Version']
        code_block_entry['version'] = code_block_node['Version']
      end
      if code_block_node['IfPackage']
        code_block_entry['if_package'] = code_block_node['IfPackage']
      end
      if code_block_node['IfNotPackage']
        code_block_entry['if_not_package'] = code_block_node['IfNotPackage']
      end

      @structure[ 'code_' + block_type ].push code_block_entry
    }
  }

  # Intro blocks (optional)
  %w(Install Upgrade Reinstall Uninstall).each { |block_type|

    intro_block_nodes = @sopm.xpath('/otrs_package/Intro' + block_type)

    next if intro_block_nodes.length == 0

    # convert to lowercase
    block_type.downcase!

    @structure[ 'code_' + block_type ] = []
    intro_block_nodes.each { |intro_block_node|

      intro_block_entry          = {}
      intro_block_entry['type']  = intro_block_node['Type']
      intro_block_entry['intro'] = intro_block_node.children[0].content

      # optional
      if intro_block_node['Version']
        intro_block_entry['version'] = intro_block_node['Version']
      end
      if intro_block_node['Lang']
        intro_block_entry['language'] = intro_block_node['Lang']
      end
      if intro_block_node['Title']
        intro_block_entry['title'] = intro_block_node['Title']
      end
      if intro_block_node['Format']
        intro_block_entry['format'] = intro_block_node['Format']
      end

      @structure[ 'code_' + block_type ].push intro_block_entry
    }
  }

  # Database blocks (optional)
  %w(Install Upgrade Reinstall Uninstall).each { |block_type|

    intro_block_nodes = @sopm.xpath('/otrs_package/Database' + block_type)

    next if intro_block_nodes.length == 0

    # convert to lowercase
    block_type.downcase!

    @structure[ 'database_' + block_type ] = []
    intro_block_nodes.each { |intro_block_node|

      next if !intro_block_node
      next if !intro_block_node.children.is_a?(Array)
      next if intro_block_node.children.empty?

      @structure[ 'database_' + block_type ].push intro_block_node.children[0].content
    }
  }

  @structure
end

#storeHash

Stores the changes to the SOPM file.

Returns:

  • (Hash)

    the parsed SOPM structure.



164
165
166
167
168
169
170
171
# File 'lib/otrs/sopm.rb', line 164

def store

  File.open(@sopm_file, 'w') { |file|
    file.write( @sopm.to_xml )
  }

  parse
end

#version(version, change_log) ⇒ Hash

Adds a new version and the changelog to the SOPM file.

Parameters:

  • version (String)

    the version number.

  • change_log (String)

    the changelog.

Returns:

  • (Hash)

    the parsed SOPM structure.



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
# File 'lib/otrs/sopm.rb', line 33

def version(version, change_log)

  fail ArgumentError, 'Version has to be a string' unless version.is_a? String
  fail ArgumentError, 'Version has to be in the format "1.0.1" for releases or "1.0.1.1" for test releases' unless /\A\d+(?:\.\d+){2,3}\z/ =~ version
  fail ArgumentError, 'Change_log hast to be a string' unless change_log.is_a? String

  # change Version
  @sopm.xpath('/otrs_package/Version').children[0].content = version

  # append ChangeLog
  change_log_nodes = @sopm.xpath('/otrs_package/ChangeLog')
  if change_log_nodes.length == 0
    change_log_nodes = @sopm.xpath('/otrs_package/Framework')
  end

  # remove tabs from ChangeLog
  change_log.gsub!(/\t/, '  ')

  # strip whitespaces
  change_log.strip!

  new_change_log_entry            = Nokogiri::XML::Node.new 'ChangeLog', sopm
  new_change_log_entry['Version'] = version
  new_change_log_entry['Date']    = Time.now
  new_change_log_entry.content    = change_log

  change_log_nodes.first.previous = new_change_log_entry.to_xml + "\n    "

  store
end

#version_delete(version_delete = nil) ⇒ Hash

Removes the given or latest (if no parameter is passed) version and removes the matching changelog from the SOPM file.

Parameters:

  • version (String, nil)

    the version number or nil if the latest should get removed.

Returns:

  • (Hash)

    the parsed SOPM structure.



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
# File 'lib/otrs/sopm.rb', line 68

def version_delete(version_delete = nil)

  change_log_nodes = @sopm.xpath('/otrs_package/ChangeLog')

  if !version_delete || version_delete == @structure['version']

    new_version = nil
    if change_log_nodes.length > 0
      @sopm.xpath('/otrs_package/ChangeLog').first.remove
      if @sopm.xpath('/otrs_package/ChangeLog').length > 0
        new_version = @sopm.xpath('/otrs_package/ChangeLog').first['Version']
      end
    end

    @sopm.xpath('/otrs_package/Version').children[0].content = new_version
  elsif change_log_nodes.length > 0

    change_log_nodes.each { |change_log_node|

      next if !change_log_node['Version'].is_a? String
      next if change_log_node['Version'] != version_delete

      change_log_node.remove

      break
    }
  end

  store
end