arr-pm 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.

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: []