qrpm 0.0.3 → 0.3.0

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.
data/lib/qrpm/parser.rb DELETED
@@ -1,183 +0,0 @@
1
-
2
- module Qrpm
3
- class Parser
4
- DICT_FIELDS = (Rpm::FIELDS - %w(requires)).map { |f| [f, true] }.to_h
5
-
6
- attr_reader :fields # Hash from field to value (which can be of any type)
7
- attr_reader :dirs # Hash from directory to list of entries
8
- attr_reader :files # List of files
9
- attr_reader :rpm # Resulting RPM object
10
-
11
- def initialize(fields)
12
- @fields = fields.dup
13
- @dirs = {}
14
- @files = []
15
- end
16
-
17
- def parse(yaml)
18
- # Collect .qrpm file variables and directories and the list of required
19
- # packages. Variables are merged into +fields+
20
- yaml.each { |k,v|
21
- if k =~ /[\/.]/ || DIRS.key?(k) || DIRS.key?(k.sub(/^pck/, ""))
22
- (dirs[k] ||= []).concat v
23
- elsif k =~ /^[\w_]+$/
24
- fields[k] = v if !fields.key?(k)
25
- else
26
- raise "Illegal key/value: #{k}: #{v}"
27
- end
28
- }
29
-
30
- # Check for mandatory variables
31
- Rpm::MANDATORY_FIELDS.each { |f|
32
- fields.key?(f) or raise "Missing mandatory variable: #{f}"
33
- }
34
-
35
- # Get full name of user
36
- fullname = Etc.getpwnam(ENV['USER'])&.gecos
37
- if fullname.nil? || fullname == ""
38
- fullname = ENV['USER']
39
- end
40
-
41
- # Defaults for description and packager fields
42
- fields["description"] ||= fields["summary"]
43
- fields["packager"] ||= fullname
44
- fields["release"] ||= "0"
45
- fields["license"] ||= "GPL"
46
-
47
- # Expand variables in fields. The expansion mechanism doesn't depend on the order
48
- # of the variables
49
- expand_fields
50
-
51
- # Expand variables in directory entries. The algorithm is simpler than in
52
- # #expand_fields because no further variable defitinitions can happend
53
- expand_dirs
54
-
55
- # Replace symbolic directory names
56
- @dirs = dirs.map { |dir, files|
57
- if DIRS.key?(dir)
58
- dir = DIRS[dir]
59
- elsif dir =~ /^pck(.*)$/ && DIRS.key?($1)
60
- dir = "#{DIRS[$1]}/#{fields["name"]}"
61
- end
62
- [dir, files]
63
- }.to_h
64
-
65
- # Build files
66
- dirs.each { |dir, nodes|
67
- nodes.each { |node|
68
- case node
69
- when Hash
70
- node = node.dup
71
- if node.key?("file")
72
- name = node.delete("name")
73
- file = node.delete("file")
74
- perm = node.delete("perm")
75
- node.empty? or raise "Illegal keys for file in directory #{dir}: #{node.keys}"
76
- files << Qrpm::File.new(dir, name, file, perm)
77
- elsif node.key?("link")
78
- name = node.delete("name")
79
- link = node.delete("link")
80
- node.empty? or raise "Illegal keys for link in directory #{dir}: #{node.keys}"
81
- files << Qrpm::Link.new(dir, name, link)
82
- else
83
- raise "Need either a 'file' or 'link' field for directory #{dir}"
84
- end
85
- when String
86
- files << Qrpm::File.new(dir, nil, node, nil)
87
- else
88
- raise "Illegal value for directory #{dir}: #{node}"
89
- end
90
- }
91
- }
92
-
93
- @rpm = Rpm.new(fields, files)
94
- end
95
-
96
- def self.parse(dict, yaml)
97
- Parser.new(dict).parse(yaml)
98
- end
99
-
100
- private
101
- MANDATORY_FIELDS = %w(name summary version)
102
-
103
- DIRS = {
104
- "etcdir" => "/etc",
105
- "bindir" => "/usr/bin",
106
- "sbindir" => "/usr/sbin",
107
- "libdir" => "/usr/lib",
108
- "libexecdir" => "/usr/libexec",
109
- "sharedir" => "/usr/share",
110
- "vardir" => "/var/lib",
111
- "spooldir" => "/var/spool",
112
- "rundir" => "/var/run",
113
- "lockdir" => "/var/lock",
114
- "cachedir" => "/var/cache",
115
- "tmpdir" => "/tmp",
116
- "logdir" => "/var/log"
117
- }
118
-
119
- # Returns array of variables in the object. Variables can be either '$name' or
120
- # '${name}'. The variables are returned in left-to-right order
121
- #
122
- def collect_variables(object, include_keys: false)
123
- case object
124
- when Array; object.map { |obj| collect_variables(obj) }
125
- when Hash; object.map { |k,v| (include_keys ? collect_variables(k) : []) + collect_variables(v) }
126
- when String; object.scan(/\$([\w_]+)|\$\{([\w_]+)\}/)
127
- when Integer, Float, true, false, nil; []
128
- else
129
- raise "Illegal object: #{object}"
130
- end.flatten.compact.uniq
131
- end
132
-
133
- # Expand variables in the given string
134
- #
135
- # The method takes care to substite left-to-rigth to avoid a variable expansion
136
- # to infer with the name of an immediately preceding variable. Eg. $a$b; if $b
137
- # is resolved to 'c' then a search would otherwise be made for a variable named
138
- # '$ac'
139
- #
140
- def expand_variables(object, include_key: false)
141
- case object
142
- when Array; object.map { |e| expand_variables(e) }
143
- when Hash; object.map { |k,v| [expand_variables(k), expand_variables(v)] }.to_h
144
- when String
145
- s = object.dup
146
- collect_variables(object).each { |k| s.sub!(/\$#{k}|\$\{#{k}\}/, fields[k].to_s) }
147
- s
148
- when Integer, Float, true, false, nil; object
149
- else
150
- raise "Illegal object: #{object}"
151
- end
152
- end
153
-
154
- # Expands fields (but not directories). The algorithm allows fields to be
155
- # defined in any order
156
- #
157
- def expand_fields
158
- variables = fields.map { |k,v| [k, collect_variables(v)] }.to_h
159
- variables.values.flatten.uniq.each { |var|
160
- fields[var].nil? || fields[var].is_a?(String) or "Can't use '#{var}' as variable"
161
- }
162
-
163
- @fields, unresolved = fields.partition { |k,v| variables[k].empty? }.map(&:to_h)
164
- changed = true
165
- while changed && !unresolved.empty?
166
- changed = false
167
- unresolved.delete_if { |k,v|
168
- if variables[k].all? { |var| fields.key? var }
169
- fields[k] = expand_variables(unresolved[k])
170
- changed = true
171
- end
172
- }
173
- end
174
- unresolved.empty? or raise "Unresolved variables: #{unresolved.join(", ")}"
175
- end
176
-
177
- def expand_dirs
178
- @dirs = expand_variables(dirs)
179
- end
180
- end
181
- end
182
-
183
-