arr-pm 0.0.10 → 0.0.11

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.

Potentially problematic release.


This version of arr-pm might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 60fcb2287ddbb0f718255da5beb0033d9459be16
4
- data.tar.gz: 1586517c23d99e2c5dead4a45128cfd49c9ff87c
2
+ SHA256:
3
+ metadata.gz: ceb08ab00b24c659ee4f0fd42d8f5c8ad77416ffff3f89e8ee18ec46ddc58383
4
+ data.tar.gz: b53d4d64c24362fb2cf27606842d8352e9f7d184f9ba3b76eb1e33b3e13b2775
5
5
  SHA512:
6
- metadata.gz: e44130d06daa88d4b84b0c800fb54dd8ca8cb4f0b75185c98e450e6b241d30fe666e4a491c6a8113c837d162b95783dcd805c293b1af5fc0d99b2e74ad86eb30
7
- data.tar.gz: 1c7b02c83d66bcc5964faeeab66b3cc179acda31225039ba60ef0e05311ab9824887830e2ee568ef7946e18d594b274e11141fde2b92eb4a3418c3b85123abd0
6
+ metadata.gz: 441b7c7a0d0851c3c4cadaf7e2e0f20d32388ba4df722ee3f76bfb3a34bb072739daf63739cf19e9d8f221a40a80f999ca47b2825043ded493d1f3363dec3e54
7
+ data.tar.gz: 815d8fff66bc8672b7e212f6c138795a9029b5e78032d26051ac114e306084f97d01519060427aeb50e9bca29dd49af5d5567370904d8881fc99179184811cd3
data/Guardfile ADDED
@@ -0,0 +1,77 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features)
6
+
7
+ ## Uncomment to clear the screen before every task
8
+ # clearing :on
9
+
10
+ ## Guard internally checks for changes in the Guardfile and exits.
11
+ ## If you want Guard to automatically start up again, run guard in a
12
+ ## shell loop, e.g.:
13
+ ##
14
+ ## $ while bundle exec guard; do echo "Restarting Guard..."; done
15
+ ##
16
+ ## Note: if you are using the `directories` clause above and you are not
17
+ ## watching the project directory ('.'), then you will want to move
18
+ ## the Guardfile to a watched dir and symlink it back, e.g.
19
+ #
20
+ # $ mkdir config
21
+ # $ mv Guardfile config/
22
+ # $ ln -s config/Guardfile .
23
+ #
24
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
25
+
26
+ # Note: The cmd option is now required due to the increasing number of ways
27
+ # rspec may be run, below are examples of the most common uses.
28
+ # * bundler: 'bundle exec rspec'
29
+ # * bundler binstubs: 'bin/rspec'
30
+ # * spring: 'bin/rspec' (This will use spring if running and you have
31
+ # installed the spring binstubs per the docs)
32
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
33
+ # * 'just' rspec: 'rspec'
34
+
35
+ guard :rspec, cmd: "bundle exec rspec" do
36
+ require "guard/rspec/dsl"
37
+ dsl = Guard::RSpec::Dsl.new(self)
38
+
39
+ # Feel free to open issues for suggestions and improvements
40
+
41
+ # RSpec files
42
+ rspec = dsl.rspec
43
+ watch(rspec.spec_helper) { rspec.spec_dir }
44
+ watch(rspec.spec_support) { rspec.spec_dir }
45
+ watch(rspec.spec_files)
46
+
47
+ # Ruby files
48
+ ruby = dsl.ruby
49
+ dsl.watch_spec_files_for(ruby.lib_files)
50
+
51
+ # Rails files
52
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
53
+ dsl.watch_spec_files_for(rails.app_files)
54
+ dsl.watch_spec_files_for(rails.views)
55
+
56
+ watch(rails.controllers) do |m|
57
+ [
58
+ rspec.spec.("routing/#{m[1]}_routing"),
59
+ rspec.spec.("controllers/#{m[1]}_controller"),
60
+ rspec.spec.("acceptance/#{m[1]}")
61
+ ]
62
+ end
63
+
64
+ # Rails config changes
65
+ watch(rails.spec_helper) { rspec.spec_dir }
66
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
67
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
68
+
69
+ # Capybara features specs
70
+ watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
71
+
72
+ # Turnip features and steps
73
+ watch(%r{^spec/acceptance/(.+)\.feature$})
74
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
75
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
76
+ end
77
+ end
data/arr-pm.gemspec CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |spec|
2
2
  files = %x{git ls-files}.split("\n")
3
3
 
4
4
  spec.name = "arr-pm"
5
- spec.version = "0.0.10"
5
+ spec.version = "0.0.11"
6
6
  spec.summary = "RPM reader and writer library"
7
7
  spec.description = "This library allows to you to read and write rpm " \
8
8
  "packages. Written in pure ruby because librpm is not available " \
data/lib/arr-pm/file.rb CHANGED
@@ -179,10 +179,12 @@ class RPM::File
179
179
  results = []
180
180
  # short-circuit if there's no :fileflags tag
181
181
  return results unless tags.include?(:fileflags)
182
- tags[:fileflags].each_with_index do |flag, i|
183
- # The :fileflags (and other :file... tags) are an array, in order of
184
- # files in the rpm payload, we want a list of paths of config files.
185
- results << files[i] if mask?(flag, FLAG_CONFIG_FILE)
182
+ if !tags[:fileflags].nil?
183
+ tags[:fileflags].each_with_index do |flag, i|
184
+ # The :fileflags (and other :file... tags) are an array, in order of
185
+ # files in the rpm payload, we want a list of paths of config files.
186
+ results << files[i] if mask?(flag, FLAG_CONFIG_FILE)
187
+ end
186
188
  end
187
189
  return results
188
190
  end # def config_files
@@ -12,16 +12,8 @@ class RPM::File::Header
12
12
  attr_accessor :data_length # rpmlib calls this field 'dl' unhelpfully
13
13
 
14
14
  HEADER_SIGNED_TYPE = 5
15
-
16
- if RUBY_VERSION =~ /^2\./
17
- # Ruby 2 forces all strings to be UTF-8, so "\x01" becomes "\u0001"
18
- # which is two bytes 00 01 which is not what we want. I can't find
19
- # a sane way to create a string without this madness in Ruby 2,
20
- # so let's just pack two 4-byte integers and go about our day.
21
- HEADER_MAGIC = [0x8eade801, 0x00000000].pack("NN")
22
- else
23
- HEADER_MAGIC = "\x8e\xad\xe8\x01\x00\x00\x00\x00"
24
- end
15
+ HEADER_MAGIC = "\x8e\xad\xe8\x01\x00\x00\x00\x00".force_encoding("BINARY")
16
+
25
17
  # magic + index_count + data_length
26
18
  HEADER_HEADER_LENGTH = HEADER_MAGIC.length + 4 + 4
27
19
  TAG_ENTRY_SIZE = 16 # tag id, type, offset, count == 16 bytes
@@ -1,3 +1,9 @@
1
1
  class RPM
2
2
  class File; end
3
3
  end
4
+
5
+ module ArrPM
6
+ module V2
7
+ class Package; end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ require "arr-pm/namespace"
2
+
3
+ module ArrPM::V2::Architecture
4
+
5
+ NOARCH = 0
6
+ I386 = 1
7
+ ALPHA = 2
8
+ SPARC = 3
9
+ MIPS = 4
10
+ PPC = 5
11
+ M68K = 6
12
+ IP = 7
13
+ RS6000 = 8
14
+ IA64 = 9
15
+ SPARC64 = 10
16
+ MIPSEL = 11
17
+ ARM = 12
18
+ MK68KMINT = 13
19
+ S390 = 14
20
+ S390X = 15
21
+ PPC64 = 16
22
+ SH = 17
23
+ XTENSA = 18
24
+ X86_64 = 19
25
+
26
+ module_function
27
+
28
+ # Is a given rpm architecture value valid?
29
+ def valid?(value)
30
+ return value >= 0 && value <= 19
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+
6
+ module ArrPM::V2::Error
7
+ class Base < StandardError; end
8
+
9
+ class InvalidMagicValue < Base
10
+ def initialize(value)
11
+ super("Got invalid magic value '#{value}'. Expected #{ArrPM::V2::Format::MAGIC}.")
12
+ end
13
+ end
14
+
15
+ class InvalidHeaderMagicValue < Base
16
+ def initialize(value)
17
+ super("Got invalid magic value '#{value}'. Expected #{ArrPM::V2::HeaderHeader::MAGIC}.")
18
+ end
19
+ end
20
+
21
+ class EmptyFile < Base; end
22
+ class ShortFile < Base; end
23
+ class InvalidVersion < Base; end
24
+ class InvalidType < Base
25
+ def initialize(value)
26
+ super("Invalid type: #{value.inspect}")
27
+ end
28
+ end
29
+ class InvalidName < Base; end
30
+ class InvalidArchitecture < Base; end
31
+
32
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+
5
+ module ArrPM::V2::Format
6
+ MAGIC = [0x8e, 0xad, 0xe8]
7
+ MAGIC_LENGTH = MAGIC.count
8
+ MAGIC_STRING = MAGIC.pack("C#{MAGIC_LENGTH}")
9
+
10
+ module_function
11
+ def valid_magic?(magic)
12
+ magic = magic.bytes if magic.is_a?(String)
13
+
14
+ magic == MAGIC
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+ require "arr-pm/v2/header_header"
6
+ require "arr-pm/v2/tag"
7
+ require "arr-pm/v2/error"
8
+
9
+ class ArrPM::V2::Header
10
+ attr_reader :tags
11
+
12
+ def load(io)
13
+ headerheader = ArrPM::V2::HeaderHeader.new
14
+ headerheader.load(io)
15
+ headerdata = io.read(headerheader.entries * 16)
16
+ tagdata = io.read(headerheader.bytesize)
17
+ parse(headerdata, headerheader.entries, tagdata)
18
+
19
+ # signature headers are padded up to an 8-byte boundar, details here:
20
+ # http://rpm.org/gitweb?p=rpm.git;a=blob;f=lib/signature.c;h=63e59c00f255a538e48cbc8b0cf3b9bd4a4dbd56;hb=HEAD#l204
21
+ # Throw away the pad.
22
+ io.read(tagdata.length % 8)
23
+ end
24
+
25
+ def parse(data, entry_count, tagdata)
26
+ @tags = entry_count.times.collect do |i|
27
+ tag_number, type_number, offset, count = data[i * 16, 16].unpack("NNNN")
28
+
29
+ tag = ArrPM::V2::Tag.new(tag_number, type_number)
30
+ tag.parse(tagdata, offset, count)
31
+ tag
32
+ end
33
+ nil
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+ require "arr-pm/v2/error"
6
+
7
+ # The header of an rpm has ... a header. Funky naming :)
8
+ class ArrPM::V2::HeaderHeader
9
+ MAGIC = [ 0x8e, 0xad, 0xe8 ]
10
+ MAGIC_LENGTH = MAGIC.count
11
+
12
+ attr_accessor :version, :entries, :bytesize
13
+
14
+ def load(io)
15
+ data = io.read(16)
16
+ parse(data)
17
+ end
18
+
19
+ def parse(data)
20
+ magic, version, reserved, entries, bytesize = data.unpack("a3Ca4NN")
21
+ self.class.validate_magic(magic.bytes)
22
+
23
+ @version = version
24
+ @entries = entries
25
+ @bytesize = bytesize
26
+ nil
27
+ end
28
+
29
+ def dump
30
+ [magic, 1, 0, @entries, @bytesize].pack("a3Ca4NN")
31
+ end
32
+
33
+ def self.validate_magic(value)
34
+ raise ArrPM::V2::Error::InvalidHeaderMagicValue, value if value != MAGIC
35
+ end
36
+ end
@@ -0,0 +1,121 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+ require "arr-pm/v2/error"
6
+
7
+ class ArrPM::V2::Lead
8
+ LENGTH = 96
9
+ MAGIC = [ 0xed, 0xab, 0xee, 0xdb ]
10
+ MAGIC_LENGTH = MAGIC.count
11
+
12
+ SIGNED_TYPE = 5
13
+
14
+ attr_accessor :major, :minor, :type, :architecture, :name, :os, :signature_type, :reserved
15
+
16
+ def validate
17
+ self.class.validate_type(type)
18
+ self.class.validate_architecture(architecture)
19
+ if name.length > 65
20
+ raise ArrPM::V2::Error::InvalidName, "Name is longer than 65 chracters. This is invalid."
21
+ end
22
+ end
23
+
24
+ def dump(io)
25
+ io.write(serialize)
26
+ end
27
+
28
+ def serialize
29
+ validate
30
+ [ *MAGIC, major, minor, type, architecture, name, os, signature_type, *reserved ].pack("C4CCnnZ66nnC16")
31
+ end
32
+
33
+ def load(io)
34
+ data = io.read(LENGTH)
35
+ parse(data)
36
+ end
37
+
38
+ def parse(bytestring)
39
+ raise ArrPM::V2::Error::EmptyFile if bytestring.nil?
40
+ data = bytestring.bytes
41
+
42
+ @magic = self.class.parse_magic(data)
43
+ @major, @minor = self.class.parse_version(data)
44
+ @type = self.class.parse_type(data)
45
+ @architecture = self.class.parse_architecture(data)
46
+ @name = self.class.parse_name(data)
47
+ @os = self.class.parse_os(data)
48
+ @signature_type = self.class.parse_signature_type(data)
49
+ @reserved = self.class.parse_reserved(data)
50
+ self
51
+ end
52
+
53
+ def signature?
54
+ @signature_type == SIGNED_TYPE
55
+ end
56
+
57
+ def self.valid_version?(version)
58
+ version == 1
59
+ end
60
+
61
+ def self.parse_magic(data)
62
+ magic = data[0, MAGIC_LENGTH]
63
+ validate_magic(magic)
64
+ magic
65
+ end
66
+
67
+ def self.validate_magic(magic)
68
+ raise ArrPM::V2::Error::InvalidMagicValue, magic unless magic == MAGIC
69
+ end
70
+
71
+ def self.parse_version(data)
72
+ offset = MAGIC_LENGTH
73
+ major, minor = data[offset, 2]
74
+ return major, minor
75
+ end
76
+
77
+ def self.parse_type(data)
78
+ offset = MAGIC_LENGTH + 2
79
+ type = data[offset, 2].pack("CC").unpack("n").first
80
+ validate_type(type)
81
+ type
82
+ end
83
+
84
+ def self.validate_type(type)
85
+ raise ArrPM::V2::Error::InvalidType, type unless ArrPM::V2::Type.valid?(type)
86
+ end
87
+
88
+ def self.parse_architecture(data)
89
+ offset = MAGIC_LENGTH + 4
90
+ architecture = data[offset, 2].pack("C*").unpack("n").first
91
+ validate_architecture(architecture)
92
+ architecture
93
+ end
94
+
95
+ def self.validate_architecture(architecture)
96
+ raise ArrPM::V2::Error::InvalidArchitecture unless ArrPM::V2::Architecture.valid?(architecture)
97
+ end
98
+
99
+ def self.parse_name(data)
100
+ offset = MAGIC_LENGTH + 6
101
+ name = data[offset, 66]
102
+ length = name.find_index(0) # find the first null byte
103
+ raise ArrPM::V2::Error::InvalidName unless length
104
+ return name[0, length].pack("C*")
105
+ end
106
+
107
+ def self.parse_os(data)
108
+ offset = MAGIC_LENGTH + 72
109
+ data[offset, 2].pack("C*").unpack("n").first
110
+ end
111
+
112
+ def self.parse_signature_type(data)
113
+ offset = MAGIC_LENGTH + 74
114
+ data[offset, 2].pack("C*").unpack("n").first
115
+ end
116
+
117
+ def self.parse_reserved(data)
118
+ offset = MAGIC_LENGTH + 76
119
+ data[offset, 16]
120
+ end
121
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+
5
+ class ArrPM::V2::RPM
6
+ attr_accessor :name
7
+ attr_accessor :epoch
8
+ attr_accessor :version
9
+ attr_accessor :release
10
+
11
+ def initialize
12
+ defaults
13
+ end
14
+
15
+ def defaults
16
+ @type = Type::BINARY
17
+ end
18
+ end
@@ -0,0 +1,295 @@
1
+ require "arr-pm/namespace"
2
+
3
+ class ArrPM::V2::Tag
4
+ module Type
5
+ NULL = 0
6
+ CHAR = 1
7
+ INT8 = 2
8
+ INT16 = 3
9
+ INT32 = 4
10
+ INT64 = 5
11
+ STRING = 6
12
+ BINARY = 7
13
+ STRING_ARRAY = 8
14
+ I18NSTRING = 9
15
+
16
+ TYPE_MAP = Hash[constants.collect { |c| [const_get(c), c] }]
17
+
18
+ def self.parse(data, type, offset, count)
19
+ case type
20
+ when NULL
21
+ nil
22
+ when CHAR
23
+ data[offset, count].unpack("A#{count}")
24
+ when INT8
25
+ data[offset, count].unpack("C" * count)
26
+ when INT16
27
+ data[offset, 2 * count].unpack("n" * count)
28
+ when INT32
29
+ data[offset, 4 * count].unpack("N" * count)
30
+ when INT64
31
+ a, b = data[offset, 8].unpack("NN")
32
+ a << 32 + b
33
+ when STRING, I18NSTRING
34
+ data[offset..-1][/^[^\0]*/]
35
+ when BINARY
36
+ data[offset, count]
37
+ when STRING_ARRAY
38
+ data[offset..-1].split("\0")[0...count]
39
+ else
40
+ raise ArrPM::V2::Error::InvalidType, type
41
+ end
42
+ end
43
+ end # module Type
44
+
45
+ HEADERIMAGE = 61
46
+ HEADERSIGNATURES = 62
47
+ HEADERIMMUTABLE = 63
48
+ HEADERREGIONS = 64
49
+ HEADERI18NTABLE = 100
50
+ SIG_BASE = 256
51
+
52
+ SIGSIZE = 257
53
+ SIGLEMD5_1 = 258
54
+ SIGPGP = 259
55
+ SIGLEMD5_2 = 260
56
+ SIGMD5 = 261
57
+ SIGGPG = 262
58
+ SIGPGP5 = 263
59
+ BADSHA1_1 = 264
60
+ BADSHA1_2 = 265
61
+ PUBKEYS = 266
62
+ DSAHEADER = 267
63
+ RSAHEADER = 268
64
+ SHA1HEADER = 269
65
+ LONGSIGSIZE = 270
66
+ LONGARCHIVESIZE = 271
67
+
68
+ NAME = 1000
69
+ VERSION = 1001
70
+ RELEASE = 1002
71
+ EPOCH = 1003
72
+ SUMMARY = 1004
73
+ DESCRIPTION = 1005
74
+ BUILDTIME = 1006
75
+ BUILDHOST = 1007
76
+ INSTALLTIME = 1008
77
+ SIZE = 1009
78
+ DISTRIBUTION = 1010
79
+ VENDOR = 1011
80
+ GIF = 1012
81
+ XPM = 1013
82
+ LICENSE = 1014
83
+ PACKAGER = 1015
84
+ GROUP = 1016
85
+ CHANGELOG = 1017
86
+ SOURCE = 1018
87
+ PATCH = 1019
88
+ URL = 1020
89
+ OS = 1021
90
+ ARCH = 1022
91
+ PREIN = 1023
92
+ POSTIN = 1024
93
+ PREUN = 1025
94
+ POSTUN = 1026
95
+ OLDFILENAMES = 1027
96
+ FILESIZES = 1028
97
+ FILESTATES = 1029
98
+ FILEMODES = 1030
99
+ FILEUIDS = 1031
100
+ FILEGIDS = 1032
101
+ FILERDEVS = 1033
102
+ FILEMTIMES = 1034
103
+ FILEDIGESTS = 1035
104
+ FILELINKTOS = 1036
105
+ FILEFLAGS = 1037
106
+ ROOT = 1038
107
+ FILEUSERNAME = 1039
108
+ FILEGROUPNAME = 1040
109
+ EXCLUDE = 1041
110
+ EXCLUSIVE = 1042
111
+ ICON = 1043
112
+ SOURCERPM = 1044
113
+ FILEVERIFYFLAGS = 1045
114
+ ARCHIVESIZE = 1046
115
+ PROVIDENAME = 1047
116
+ REQUIREFLAGS = 1048
117
+ REQUIRENAME = 1049
118
+ REQUIREVERSION = 1050
119
+ NOSOURCE = 1051
120
+ NOPATCH = 1052
121
+ CONFLICTFLAGS = 1053
122
+ CONFLICTNAME = 1054
123
+ CONFLICTVERSION = 1055
124
+ DEFAULTPREFIX = 1056
125
+ BUILDROOT = 1057
126
+ INSTALLPREFIX = 1058
127
+ EXCLUDEARCH = 1059
128
+ EXCLUDEOS = 1060
129
+ EXCLUSIVEARCH = 1061
130
+ EXCLUSIVEOS = 1062
131
+ AUTOREQPROV = 1063
132
+ RPMVERSION = 1064
133
+ TRIGGERSCRIPTS = 1065
134
+ TRIGGERNAME = 1066
135
+ TRIGGERVERSION = 1067
136
+ TRIGGERFLAGS = 1068
137
+ TRIGGERINDEX = 1069
138
+ VERIFYSCRIPT = 1079
139
+ CHANGELOGTIME = 1080
140
+ CHANGELOGNAME = 1081
141
+ CHANGELOGTEXT = 1082
142
+ BROKENMD5 = 1083
143
+ PREREQ = 1084
144
+ PREINPROG = 1085
145
+ POSTINPROG = 1086
146
+ PREUNPROG = 1087
147
+ POSTUNPROG = 1088
148
+ BUILDARCHS = 1089
149
+ OBSOLETENAME = 1090
150
+ VERIFYSCRIPTPROG = 1091
151
+ TRIGGERSCRIPTPROG = 1092
152
+ DOCDIR = 1093
153
+ COOKIE = 1094
154
+ FILEDEVICES = 1095
155
+ FILEINODES = 1096
156
+ FILELANGS = 1097
157
+ PREFIXES = 1098
158
+ INSTPREFIXES = 1099
159
+ TRIGGERIN = 1100
160
+ TRIGGERUN = 1101
161
+ TRIGGERPOSTUN = 1102
162
+ AUTOREQ = 1103
163
+ AUTOPROV = 1104
164
+ CAPABILITY = 1105
165
+ SOURCEPACKAGE = 1106
166
+ OLDORIGFILENAMES = 1107
167
+ BUILDPREREQ = 1108
168
+ BUILDREQUIRES = 1109
169
+ BUILDCONFLICTS = 1110
170
+ BUILDMACROS = 1111
171
+ PROVIDEFLAGS = 1112
172
+ PROVIDEVERSION = 1113
173
+ OBSOLETEFLAGS = 1114
174
+ OBSOLETEVERSION = 1115
175
+ DIRINDEXES = 1116
176
+ BASENAMES = 1117
177
+ DIRNAMES = 1118
178
+ ORIGDIRINDEXES = 1119
179
+ ORIGBASENAMES = 1120
180
+ ORIGDIRNAMES = 1121
181
+ OPTFLAGS = 1122
182
+ DISTURL = 1123
183
+ PAYLOADFORMAT = 1124
184
+ PAYLOADCOMPRESSOR = 1125
185
+ PAYLOADFLAGS = 1126
186
+ INSTALLCOLOR = 1127
187
+ INSTALLTID = 1128
188
+ REMOVETID = 1129
189
+ SHA1RHN = 1130
190
+ RHNPLATFORM = 1131
191
+ PLATFORM = 1132
192
+ PATCHESNAME = 1133
193
+ PATCHESFLAGS = 1134
194
+ PATCHESVERSION = 1135
195
+ CACHECTIME = 1136
196
+ CACHEPKGPATH = 1137
197
+ CACHEPKGSIZE = 1138
198
+ CACHEPKGMTIME = 1139
199
+ FILECOLORS = 1140
200
+ FILECLASS = 1141
201
+ CLASSDICT = 1142
202
+ FILEDEPENDSX = 1143
203
+ FILEDEPENDSN = 1144
204
+ DEPENDSDICT = 1145
205
+ SOURCEPKGID = 1146
206
+ FILECONTEXTS = 1147
207
+ FSCONTEXTS = 1148
208
+ RECONTEXTS = 1149
209
+ POLICIES = 1150
210
+ PRETRANS = 1151
211
+ POSTTRANS = 1152
212
+ PRETRANSPROG = 1153
213
+ POSTTRANSPROG = 1154
214
+ DISTTAG = 1155
215
+ SUGGESTSNAME = 1156
216
+ SUGGESTSVERSION = 1157
217
+ SUGGESTSFLAGS = 1158
218
+ ENHANCESNAME = 1159
219
+ ENHANCESVERSION = 1160
220
+ ENHANCESFLAGS = 1161
221
+ PRIORITY = 1162
222
+ CVSID = 1163
223
+ BLINKPKGID = 1164
224
+ BLINKHDRID = 1165
225
+ BLINKNEVRA = 1166
226
+ FLINKPKGID = 1167
227
+ FLINKHDRID = 1168
228
+ FLINKNEVRA = 1169
229
+ PACKAGEORIGIN = 1170
230
+ TRIGGERPREIN = 1171
231
+ BUILDSUGGESTS = 1172
232
+ BUILDENHANCES = 1173
233
+ SCRIPTSTATES = 1174
234
+ SCRIPTMETRICS = 1175
235
+ BUILDCPUCLOCK = 1176
236
+ FILEDIGESTALGOS = 1177
237
+ VARIANTS = 1178
238
+ XMAJOR = 1179
239
+ XMINOR = 1180
240
+ REPOTAG = 1181
241
+ KEYWORDS = 1182
242
+ BUILDPLATFORMS = 1183
243
+ PACKAGECOLOR = 1184
244
+ PACKAGEPREFCOLOR = 1185
245
+ XATTRSDICT = 1186
246
+ FILEXATTRSX = 1187
247
+ DEPATTRSDICT = 1188
248
+ CONFLICTATTRSX = 1189
249
+ OBSOLETEATTRSX = 1190
250
+ PROVIDEATTRSX = 1191
251
+ REQUIREATTRSX = 1192
252
+ BUILDPROVIDES = 1193
253
+ BUILDOBSOLETES = 1194
254
+ DBINSTANCE = 1195
255
+ NVRA = 1196
256
+ FILENAMES = 5000
257
+ FILEPROVIDE = 5001
258
+ FILEREQUIRE = 5002
259
+ FSNAMES = 5003
260
+ FSSIZES = 5004
261
+ TRIGGERCONDS = 5005
262
+ TRIGGERTYPE = 5006
263
+ ORIGFILENAMES = 5007
264
+ LONGFILESIZES = 5008
265
+ LONGSIZE = 5009
266
+ FILECAPS = 5010
267
+ FILEDIGESTALGO = 5011
268
+ BUGURL = 5012
269
+ EVR = 5013
270
+ NVR = 5014
271
+ NEVR = 5015
272
+ NEVRA = 5016
273
+ HEADERCOLOR = 5017
274
+ VERBOSE = 5018
275
+ EPOCHNUM = 5019
276
+ ENCODING = 5062
277
+
278
+ TAG_MAP = Hash[constants.collect { |c| [const_get(c), c] }]
279
+
280
+ attr_accessor :tag, :type, :value
281
+
282
+ def initialize(tag_number, type_number)
283
+ @tag = self.class::TAG_MAP[tag_number] || tag_number
284
+ @type = type_number
285
+ end
286
+
287
+ def parse(data, offset, count)
288
+ @value = Type.parse(data, @type, offset, count)
289
+ nil
290
+ end
291
+
292
+ def inspect
293
+ format("<%s#%s> %s/%d value=%s>", self.class.name, self.object_id, @tag, @type, @value.inspect)
294
+ end
295
+ end # module ArrPM::V2::Tag
@@ -0,0 +1,15 @@
1
+ require "arr-pm/namespace"
2
+
3
+ module ArrPM::V2::Type
4
+ BINARY = 0
5
+ SOURCE = 1
6
+
7
+ module_function
8
+
9
+ # Is a given rpm type value valid?
10
+ #
11
+ # The only valid types are BINARY (0) or SOURCE (1)
12
+ def valid?(value)
13
+ return (value == BINARY || value == SOURCE)
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ require "flores/random"
4
+
5
+ require "arr-pm/v2/header"
6
+ require "arr-pm/v2/type"
7
+ require "arr-pm/v2/architecture"
8
+ require "json"
9
+
10
+ describe ArrPM::V2::Header do
11
+ context "with a known good rpm" do
12
+ let(:path) { File.join(File.dirname(__FILE__), "../../fixtures/example-1.0-1.x86_64.rpm") }
13
+ let(:file) { File.new(path) }
14
+
15
+ before do
16
+ lead = ArrPM::V2::Lead.new
17
+ lead.load(file)
18
+
19
+ # Throw away the signature if we have one
20
+ described_class.new.load(file) if lead.signature?
21
+
22
+ subject.load(file)
23
+ end
24
+
25
+ expectations = JSON.parse(File.read(File.join(File.dirname(__FILE__), "../../fixtures/example.json")))
26
+
27
+ expectations.each do |name, expected_value|
28
+ it "should have expected value for the #{name} tag" do
29
+ tag = subject.tags.find { |t| t.tag.to_s == name }
30
+ expect(tag.value).to be == expected_value
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+
3
+ require "flores/random"
4
+
5
+ require "arr-pm/v2/lead"
6
+ require "arr-pm/v2/type"
7
+ require "arr-pm/v2/architecture"
8
+
9
+ describe ArrPM::V2::Lead do
10
+ let(:major) { Flores::Random.integer(0..255) }
11
+ let(:minor) { Flores::Random.integer(0..255) }
12
+ let(:magic) { described_class::MAGIC }
13
+ let(:type) { ArrPM::V2::Type::BINARY }
14
+ let(:architecture) { ArrPM::V2::Architecture::I386 }
15
+ let(:os) { 0 }
16
+ let(:os_bytes) { [os].pack("n").unpack("C2") }
17
+ let(:signature_type) { 0 }
18
+ let(:signature_type_bytes) { [signature_type].pack("n").unpack("C2") }
19
+ let(:longname) { "test-1.0-1" }
20
+ let(:longnamebytes) { longname.bytes + (66-longname.bytesize).times.collect { 0 } }
21
+ let(:leadbytes) { magic + [major, minor] + [0, type, 0, architecture] + longnamebytes + os_bytes + signature_type_bytes + 16.times.collect { 0 } }
22
+ let(:lead) { leadbytes.pack("C*") }
23
+
24
+ describe ".parse_magic" do
25
+ context "when given an invalid magic value" do
26
+ # Generate random bytes for the magic value, should be bad.
27
+ let(:magic) { Flores::Random.iterations(0..10).collect { Flores::Random.integer(0..255) } }
28
+
29
+ it "should fail" do
30
+ expect { described_class.parse_magic(leadbytes) }.to raise_error(ArrPM::V2::Error::InvalidMagicValue)
31
+ end
32
+ end
33
+
34
+ context "when given a valid magic value" do
35
+ it "should succeed" do
36
+ expect { described_class.parse_magic(leadbytes) }.not_to raise_error
37
+ end
38
+ end
39
+ end
40
+
41
+ describe ".parse_version" do
42
+ context "when given an invalid version value" do
43
+ let(:data) { magic + [major, minor] }
44
+
45
+ it "should return an array of two values " do
46
+ expect(described_class.parse_version(leadbytes)).to be == [major, minor]
47
+ end
48
+ end
49
+ end
50
+
51
+ describe ".parse_type" do
52
+ context "when given an invalid type" do
53
+ let(:type) { Flores::Random.integer(2..1000) }
54
+ it "should fail" do
55
+ expect { described_class.parse_type(leadbytes) }.to raise_error(ArrPM::V2::Error::InvalidType)
56
+ end
57
+ end
58
+ context "with a valid type" do
59
+ it "should return the type" do
60
+ expect(described_class.parse_type(leadbytes)).to be == type
61
+ end
62
+ end
63
+ end
64
+
65
+ describe ".parse_name" do
66
+ context "with a valid name" do
67
+ it "should return the name" do
68
+ expect(described_class.parse_name(leadbytes)).to be == longname
69
+ end
70
+ end
71
+ end
72
+
73
+ describe ".parse_signature_type" do
74
+ it "should return the signature type" do
75
+ expect(described_class.parse_signature_type(leadbytes)).to be == signature_type
76
+ end
77
+ end
78
+
79
+ describe ".parse_reserved" do
80
+ it "should return exactly 16 bytes" do
81
+ expect(described_class.parse_reserved(leadbytes).count).to be == 16
82
+ end
83
+ end
84
+
85
+ describe "#parse" do
86
+ before do
87
+ subject.parse(lead)
88
+ end
89
+
90
+ it "should have a correct parsed values" do
91
+ expect(subject.name).to be == longname
92
+ expect(subject.major).to be == major
93
+ expect(subject.minor).to be == minor
94
+ expect(subject.type).to be == type
95
+ expect(subject.architecture).to be == architecture
96
+ end
97
+ end
98
+
99
+ describe "#dump" do
100
+ before do
101
+ subject.parse(lead)
102
+ end
103
+
104
+ let(:blob) { subject.serialize }
105
+
106
+ it "should parse successfully" do
107
+ subject.parse(blob)
108
+ end
109
+ end
110
+
111
+ context "with a known good rpm" do
112
+ let(:path) { File.join(File.dirname(__FILE__), "../../fixtures/example-1.0-1.x86_64.rpm") }
113
+
114
+ before do
115
+ subject.load(File.new(path))
116
+ end
117
+
118
+ it "should have expected values" do
119
+ expect(subject.name).to be == "example-1.0-1"
120
+ expect(subject.major).to be == 3
121
+ expect(subject.minor).to be == 0
122
+ expect(subject.architecture).to be == architecture
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,55 @@
1
+ {
2
+ "NAME": "example",
3
+ "VERSION": "1.0",
4
+ "RELEASE": "1",
5
+ "SUMMARY": "no description given",
6
+ "DESCRIPTION": "no description given",
7
+ "BUILDTIME": [
8
+ 1466326707
9
+ ],
10
+ "BUILDHOST": "localhost",
11
+ "SIZE": [
12
+ 0
13
+ ],
14
+ "VENDOR": "none",
15
+ "LICENSE": "unknown",
16
+ "PACKAGER": "<jls@localhost.localdomain>",
17
+ "GROUP": "default",
18
+ "URL": "http://example.com/no-uri-given",
19
+ "OS": "linux",
20
+ "ARCH": "x86_64",
21
+ "SOURCERPM": "example-1.0-1.src.rpm",
22
+ "PROVIDENAME": [
23
+ "example",
24
+ "example(x86-64)"
25
+ ],
26
+ "REQUIREFLAGS": [
27
+ 16777226,
28
+ 16777226
29
+ ],
30
+ "REQUIRENAME": [
31
+ "rpmlib(CompressedFileNames)",
32
+ "rpmlib(PayloadFilesHavePrefix)"
33
+ ],
34
+ "REQUIREVERSION": [
35
+ "3.0.4-1",
36
+ "4.0-1"
37
+ ],
38
+ "RPMVERSION": "4.13.0-rc1",
39
+ "PREFIXES": [
40
+ "/"
41
+ ],
42
+ "PROVIDEFLAGS": [
43
+ 8,
44
+ 8
45
+ ],
46
+ "PROVIDEVERSION": [
47
+ "1.0-1",
48
+ "1.0-1"
49
+ ],
50
+ "PAYLOADFORMAT": "cpio",
51
+ "PAYLOADCOMPRESSOR": "gzip",
52
+ "PAYLOADFLAGS": "9",
53
+ "PLATFORM": "x86_64-redhat-linux-gnu",
54
+ "ENCODING": "utf-8"
55
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arr-pm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-14 00:00:00.000000000 Z
11
+ date: 2021-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cabin
@@ -50,6 +50,7 @@ files:
50
50
  - ".gitignore"
51
51
  - ".rubocop.yml"
52
52
  - Gemfile
53
+ - Guardfile
53
54
  - LICENSE
54
55
  - Makefile
55
56
  - README.md
@@ -63,11 +64,24 @@ files:
63
64
  - lib/arr-pm/file/tag.rb
64
65
  - lib/arr-pm/namespace.rb
65
66
  - lib/arr-pm/requires.rb
66
- homepage:
67
+ - lib/arr-pm/v2/architecture.rb
68
+ - lib/arr-pm/v2/error.rb
69
+ - lib/arr-pm/v2/format.rb
70
+ - lib/arr-pm/v2/header.rb
71
+ - lib/arr-pm/v2/header_header.rb
72
+ - lib/arr-pm/v2/lead.rb
73
+ - lib/arr-pm/v2/package.rb
74
+ - lib/arr-pm/v2/tag.rb
75
+ - lib/arr-pm/v2/type.rb
76
+ - spec/arr-pm/v2/header_spec.rb
77
+ - spec/arr-pm/v2/lead_spec.rb
78
+ - spec/fixtures/example-1.0-1.x86_64.rpm
79
+ - spec/fixtures/example.json
80
+ homepage:
67
81
  licenses:
68
82
  - Apache 2
69
83
  metadata: {}
70
- post_install_message:
84
+ post_install_message:
71
85
  rdoc_options: []
72
86
  require_paths:
73
87
  - lib
@@ -83,9 +97,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
97
  - !ruby/object:Gem::Version
84
98
  version: '0'
85
99
  requirements: []
86
- rubyforge_project:
87
- rubygems_version: 2.4.3
88
- signing_key:
100
+ rubygems_version: 3.2.15
101
+ signing_key:
89
102
  specification_version: 4
90
103
  summary: RPM reader and writer library
91
104
  test_files: []