ruby-augeas 0.4.1 → 0.6.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.
- checksums.yaml +7 -0
- data/COPYING +38 -46
- data/NEWS +26 -1
- data/README.md +86 -0
- data/Rakefile +12 -8
- data/ext/augeas/_augeas.c +238 -30
- data/ext/augeas/_augeas.h +48 -0
- data/ext/augeas/extconf.rb +4 -0
- data/lib/augeas/facade.rb +326 -0
- data/lib/augeas.rb +94 -0
- data/tests/tc_augeas.rb +85 -2
- data/tests/tc_facade.rb +554 -0
- metadata +32 -53
- data/README.rdoc +0 -34
@@ -0,0 +1,326 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
##
|
3
|
+
# augeas.rb: Ruby wrapper for augeas
|
4
|
+
#
|
5
|
+
# Copyright (C) 2008 Red Hat Inc.
|
6
|
+
# Copyright (C) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
7
|
+
#
|
8
|
+
# This library is free software; you can redistribute it and/or
|
9
|
+
# modify it under the terms of the GNU Lesser General Public
|
10
|
+
# License as published by the Free Software Foundation; either
|
11
|
+
# version 2.1 of the License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This library is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16
|
+
# Lesser General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Lesser General Public
|
19
|
+
# License along with this library; if not, write to the Free Software
|
20
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
21
|
+
#
|
22
|
+
# Authors: Ionuț Arțăriși <iartarisi@suse.cz>
|
23
|
+
# Bryan Kearney <bkearney@redhat.com>
|
24
|
+
# Artem Sheremet <dot.doom@gmail.com>
|
25
|
+
##
|
26
|
+
|
27
|
+
# Do not require this file explicitly; instead require "augeas"
|
28
|
+
|
29
|
+
# Wrapper class for the augeas[http://augeas.net] library.
|
30
|
+
class Augeas::Facade
|
31
|
+
private_class_method :new
|
32
|
+
|
33
|
+
def self.create(opts={}, &block)
|
34
|
+
# aug_flags is a bitmask in the underlying library, we add all the
|
35
|
+
# values of the flags which were set to true to the default value
|
36
|
+
# Augeas::NONE (which is 0)
|
37
|
+
aug_flags = defined?(Augeas::NO_ERR_CLOSE) ? Augeas::NO_ERR_CLOSE : Augeas::NONE
|
38
|
+
|
39
|
+
flags = {
|
40
|
+
:type_check => Augeas::TYPE_CHECK,
|
41
|
+
:no_stdinc => Augeas::NO_STDINC,
|
42
|
+
:no_load => Augeas::NO_LOAD,
|
43
|
+
:no_modl_autoload => Augeas::NO_MODL_AUTOLOAD,
|
44
|
+
:enable_span => Augeas::ENABLE_SPAN
|
45
|
+
}
|
46
|
+
save_modes = {
|
47
|
+
:backup => Augeas::SAVE_BACKUP,
|
48
|
+
:newfile => Augeas::SAVE_NEWFILE,
|
49
|
+
:noop => Augeas::SAVE_NOOP
|
50
|
+
}
|
51
|
+
opts.each_key do |key|
|
52
|
+
if flags.key? key
|
53
|
+
aug_flags |= flags[key]
|
54
|
+
elsif key == :save_mode
|
55
|
+
if save_modes[opts[:save_mode]]
|
56
|
+
aug_flags |= save_modes[opts[:save_mode]]
|
57
|
+
else
|
58
|
+
raise ArgumentError, "Invalid save mode #{opts[:save_mode]}."
|
59
|
+
end
|
60
|
+
elsif key != :root && key != :loadpath
|
61
|
+
raise ArgumentError, "Unknown argument #{key}."
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
aug = Augeas::Facade::open3(opts[:root], opts[:loadpath], aug_flags)
|
66
|
+
|
67
|
+
begin
|
68
|
+
aug.send(:raise_last_error)
|
69
|
+
rescue
|
70
|
+
aug.close
|
71
|
+
raise
|
72
|
+
end
|
73
|
+
|
74
|
+
if block_given?
|
75
|
+
begin
|
76
|
+
yield aug
|
77
|
+
ensure
|
78
|
+
aug.close
|
79
|
+
end
|
80
|
+
else
|
81
|
+
return aug
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get the value associated with +path+.
|
86
|
+
def get(path)
|
87
|
+
run_command :augeas_get, path
|
88
|
+
end
|
89
|
+
|
90
|
+
# Return true if there is an entry for this path, false otherwise
|
91
|
+
def exists(path)
|
92
|
+
run_command :augeas_exists, path
|
93
|
+
end
|
94
|
+
|
95
|
+
# Set one or multiple elements to path.
|
96
|
+
# Multiple elements are mainly sensible with a path like
|
97
|
+
# .../array[last()+1], since this will append all elements.
|
98
|
+
def set(path, *values)
|
99
|
+
values.flatten.each { |v| run_command :augeas_set, path, v }
|
100
|
+
end
|
101
|
+
|
102
|
+
# Set multiple nodes in one operation. Find or create a node matching SUB
|
103
|
+
# by interpreting SUB as a path expression relative to each node matching
|
104
|
+
# BASE. If SUB is '.', the nodes matching BASE will be modified.
|
105
|
+
|
106
|
+
# +base+ the base node
|
107
|
+
# +sub+ the subtree relative to the base
|
108
|
+
# +value+ the value for the nodes
|
109
|
+
def setm(base, sub, value)
|
110
|
+
run_command :augeas_setm, base, sub, value
|
111
|
+
end
|
112
|
+
|
113
|
+
# Remove all nodes matching path expression +path+ and all their
|
114
|
+
# children.
|
115
|
+
# Raises an <tt>Augeas::InvalidPathError</tt> when the +path+ is invalid.
|
116
|
+
def rm(path)
|
117
|
+
run_command :augeas_rm, path
|
118
|
+
end
|
119
|
+
|
120
|
+
# Return an Array of all the paths that match the path expression +path+
|
121
|
+
#
|
122
|
+
# Returns an empty Array if no paths were found.
|
123
|
+
# Raises an <tt>Augeas::InvalidPathError</tt> when the +path+ is invalid.
|
124
|
+
def match(path)
|
125
|
+
run_command :augeas_match, path
|
126
|
+
end
|
127
|
+
|
128
|
+
# Create the +path+ with empty value if it doesn't exist
|
129
|
+
def touch(path)
|
130
|
+
set(path, nil) if match(path).empty?
|
131
|
+
end
|
132
|
+
|
133
|
+
# Evaluate +expr+ and set the variable +name+ to the resulting
|
134
|
+
# nodeset. The variable can be used in path expressions as $name.
|
135
|
+
# Note that +expr+ is evaluated when the variable is defined, not when
|
136
|
+
# it is used.
|
137
|
+
def defvar(name, expr)
|
138
|
+
run_command :augeas_defvar, name, expr
|
139
|
+
end
|
140
|
+
|
141
|
+
# Define the variable +name+ to the result of evaluating +expr+, which
|
142
|
+
# must be a nodeset. If no node matching +expr+ exists yet, one is
|
143
|
+
# created and +name+ will refer to it. When a node is created and
|
144
|
+
# +value+ is given, the new node's value is set to +value+.
|
145
|
+
def defnode(name, expr, value=nil)
|
146
|
+
run_command :augeas_defnode, name, expr, value
|
147
|
+
end
|
148
|
+
|
149
|
+
# Clear the +path+, i.e. make its value +nil+
|
150
|
+
def clear(path)
|
151
|
+
augeas_set(path, nil)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Add a transform under <tt>/augeas/load</tt>
|
155
|
+
#
|
156
|
+
# The HASH can contain the following entries
|
157
|
+
# * <tt>:lens</tt> - the name of the lens to use
|
158
|
+
# * <tt>:name</tt> - a unique name; use the module name of the LENS
|
159
|
+
# when omitted
|
160
|
+
# * <tt>:incl</tt> - a list of glob patterns for the files to transform
|
161
|
+
# * <tt>:excl</tt> - a list of the glob patterns to remove from the
|
162
|
+
# list that matches <tt>:incl</tt>
|
163
|
+
def transform(hash)
|
164
|
+
lens = hash[:lens]
|
165
|
+
name = hash[:name]
|
166
|
+
incl = hash[:incl]
|
167
|
+
excl = hash[:excl]
|
168
|
+
raise ArgumentError, "No lens specified" unless lens
|
169
|
+
raise ArgumentError, "No files to include" unless incl
|
170
|
+
name = lens.split(".")[0].sub("@", "") unless name
|
171
|
+
|
172
|
+
xfm = "/augeas/load/#{name}/"
|
173
|
+
set(xfm + "lens", lens)
|
174
|
+
set(xfm + "incl[last()+1]", incl)
|
175
|
+
set(xfm + "excl[last()+1]", excl) if excl
|
176
|
+
end
|
177
|
+
|
178
|
+
# Clear all transforms under <tt>/augeas/load</tt>. If +load+
|
179
|
+
# is called right after this, there will be no files
|
180
|
+
# under +/files+
|
181
|
+
def clear_transforms
|
182
|
+
rm("/augeas/load/*")
|
183
|
+
end
|
184
|
+
|
185
|
+
# Write all pending changes to disk.
|
186
|
+
# Raises <tt>Augeas::CommandExecutionError</tt> if saving fails.
|
187
|
+
def save
|
188
|
+
begin
|
189
|
+
run_command :augeas_save
|
190
|
+
rescue Augeas::CommandExecutionError => e
|
191
|
+
raise e, 'Saving failed. Search the augeas tree in /augeas//error ' <<
|
192
|
+
'for the actual errors.'
|
193
|
+
end
|
194
|
+
|
195
|
+
nil
|
196
|
+
end
|
197
|
+
|
198
|
+
def clearm(path, sub)
|
199
|
+
setm(path, sub, nil)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Load files according to the transforms in /augeas/load or those
|
203
|
+
# defined via <tt>transform</tt>. A transform Foo is represented
|
204
|
+
# with a subtree /augeas/load/Foo. Underneath /augeas/load/Foo, one
|
205
|
+
# node labeled 'lens' must exist, whose value is the fully
|
206
|
+
# qualified name of a lens, for example 'Foo.lns', and multiple
|
207
|
+
# nodes 'incl' and 'excl' whose values are globs that determine
|
208
|
+
# which files are transformed by that lens. It is an error if one
|
209
|
+
# file can be processed by multiple transforms.
|
210
|
+
def load
|
211
|
+
begin
|
212
|
+
run_command :augeas_load
|
213
|
+
rescue Augeas::CommandExecutionError => e
|
214
|
+
raise e, "Loading failed. Search the augeas tree in /augeas//error"+
|
215
|
+
"for the actual errors."
|
216
|
+
end
|
217
|
+
|
218
|
+
nil
|
219
|
+
end
|
220
|
+
|
221
|
+
# Move node +src+ to +dst+. +src+ must match exactly one node in
|
222
|
+
# the tree. +dst+ must either match exactly one node in the tree,
|
223
|
+
# or may not exist yet. If +dst+ exists already, it and all its
|
224
|
+
# descendants are deleted. If +dst+ does not exist yet, it and all
|
225
|
+
# its missing ancestors are created.
|
226
|
+
#
|
227
|
+
# Raises <tt>Augeas::NoMatchError</tt> if the +src+ node does not exist
|
228
|
+
# Raises <tt>Augeas::MultipleMatchesError</tt> if there were
|
229
|
+
# multiple matches in +src+
|
230
|
+
# Raises <tt>Augeas::DescendantError</tt> if the +dst+ node is a
|
231
|
+
# descendant of the +src+ node.
|
232
|
+
def mv(src, dst)
|
233
|
+
run_command :augeas_mv, src, dst
|
234
|
+
end
|
235
|
+
|
236
|
+
# Get the filename, label and value position in the text of this node
|
237
|
+
#
|
238
|
+
# Raises <tt>Augeas::NoMatchError</tt> if the node could not be found
|
239
|
+
# Raises <tt>Augeas::NoSpanInfo</tt> if the node associated with
|
240
|
+
# +path+ doesn't belong to a file or doesn't exist
|
241
|
+
def span(path)
|
242
|
+
run_command :augeas_span, path
|
243
|
+
end
|
244
|
+
|
245
|
+
# Run one or more newline-separated commands specified by +text+,
|
246
|
+
# returns an array of [successful_commands_number, output] or
|
247
|
+
# [-2, output] in case 'quit' command has been encountered.
|
248
|
+
# Raises <tt>Augeas::CommandExecutionError</tt> if gets an invalid command
|
249
|
+
def srun(text)
|
250
|
+
run_command(:augeas_srun, text)
|
251
|
+
end
|
252
|
+
|
253
|
+
# Lookup the label associated with +path+
|
254
|
+
# Raises <tt>Augeas::NoMatchError</tt> if the +path+ node does not exist
|
255
|
+
def label(path)
|
256
|
+
run_command :augeas_label, path
|
257
|
+
end
|
258
|
+
|
259
|
+
# Rename the label of all nodes matching +path+ to +label+
|
260
|
+
# Raises <tt>Augeas::NoMatchError</tt> if the +path+ node does not exist
|
261
|
+
# Raises <tt>Augeas::InvalidLabelError</tt> if +label+ is invalid
|
262
|
+
def rename(path, label)
|
263
|
+
run_command :augeas_rename, path, label
|
264
|
+
end
|
265
|
+
|
266
|
+
# Use the value of node +node+ as a string and transform it into a tree
|
267
|
+
# using the lens +lens+ and store it in the tree at +path+,
|
268
|
+
# which will be overwritten. +path+ and +node+ are path expressions.
|
269
|
+
def text_store(lens, node, path)
|
270
|
+
run_command :augeas_text_store, lens, node, path
|
271
|
+
end
|
272
|
+
|
273
|
+
# Transform the tree at +path+ into a string lens +lens+ and store it
|
274
|
+
# in the node +node_out+, assuming the tree was initially generated using
|
275
|
+
# the value of node +node_in+. +path+, +node_in+ and +node_out+ are path expressions.
|
276
|
+
def text_retrieve(lens, node_in, path, node_out)
|
277
|
+
run_command :augeas_text_retrieve, lens, node_in, path, node_out
|
278
|
+
end
|
279
|
+
|
280
|
+
# Make +label+ a sibling of +path+ by inserting it directly before
|
281
|
+
# or after +path+.
|
282
|
+
# The boolean +before+ determines if +label+ is inserted before or
|
283
|
+
# after +path+.
|
284
|
+
def insert(path, label, before)
|
285
|
+
run_command :augeas_insert, path, label, before
|
286
|
+
end
|
287
|
+
|
288
|
+
# Set path expression context to +path+ (in /augeas/context)
|
289
|
+
def context=(path)
|
290
|
+
set('/augeas/context', path)
|
291
|
+
end
|
292
|
+
|
293
|
+
# Get path expression context (from /augeas/context)
|
294
|
+
def context
|
295
|
+
get('/augeas/context')
|
296
|
+
end
|
297
|
+
|
298
|
+
private
|
299
|
+
|
300
|
+
# Run a command and raise any errors that happen due to execution.
|
301
|
+
#
|
302
|
+
# +cmd+ name of the Augeas command to run
|
303
|
+
# +params+ parameters with which +cmd+ will be called
|
304
|
+
#
|
305
|
+
# Returns whatever the original +cmd+ returns
|
306
|
+
def run_command(cmd, *params)
|
307
|
+
result = self.send cmd, *params
|
308
|
+
|
309
|
+
raise_last_error
|
310
|
+
|
311
|
+
if result.kind_of? Integer and result < 0
|
312
|
+
# we raise CommandExecutionError here, because this is the error that
|
313
|
+
# augtool raises in this case as well
|
314
|
+
raise Augeas::CommandExecutionError, "Command failed. Return code was #{result}."
|
315
|
+
end
|
316
|
+
|
317
|
+
return result
|
318
|
+
end
|
319
|
+
|
320
|
+
def raise_last_error
|
321
|
+
error_cache = error
|
322
|
+
unless error_cache[:code].zero?
|
323
|
+
raise Augeas::ERRORS_HASH[error_cache[:code]], "#{error_cache[:message]} #{error_cache[:details]}"
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
data/lib/augeas.rb
CHANGED
@@ -21,12 +21,83 @@
|
|
21
21
|
##
|
22
22
|
|
23
23
|
require "_augeas"
|
24
|
+
require "augeas/facade"
|
24
25
|
|
25
26
|
# Wrapper class for the augeas[http://augeas.net] library.
|
26
27
|
class Augeas
|
27
28
|
private_class_method :new
|
28
29
|
|
29
30
|
class Error < RuntimeError; end
|
31
|
+
class NoMemoryError < Error; end
|
32
|
+
class InternalError < Error; end
|
33
|
+
class InvalidPathError < Error; end
|
34
|
+
class NoMatchError < Error; end
|
35
|
+
class MultipleMatchesError < Error; end
|
36
|
+
class LensSyntaxError < Error; end
|
37
|
+
class LensNotFoundError < Error; end
|
38
|
+
class MultipleTransformsError < Error; end
|
39
|
+
class NoSpanInfoError < Error; end
|
40
|
+
class DescendantError < Error; end
|
41
|
+
class CommandExecutionError < Error; end
|
42
|
+
class InvalidArgumentError < Error; end
|
43
|
+
class InvalidLabelError < Error; end
|
44
|
+
ERRORS_HASH = Hash[{
|
45
|
+
# the cryptic error names come from the C library, we just make
|
46
|
+
# them more ruby and more human
|
47
|
+
:ENOMEM => NoMemoryError,
|
48
|
+
:EINTERNAL => InternalError,
|
49
|
+
:EPATHX => InvalidPathError,
|
50
|
+
:ENOMATCH => NoMatchError,
|
51
|
+
:EMMATCH => MultipleMatchesError,
|
52
|
+
:ESYNTAX => LensSyntaxError,
|
53
|
+
:ENOLENS => LensNotFoundError,
|
54
|
+
:EMXFM => MultipleTransformsError,
|
55
|
+
:ENOSPAN => NoSpanInfoError,
|
56
|
+
:EMVDESC => DescendantError,
|
57
|
+
:ECMDRUN => CommandExecutionError,
|
58
|
+
:EBADARG => InvalidArgumentError,
|
59
|
+
:ELABEL => InvalidLabelError,
|
60
|
+
}.map { |k, v| [(const_get(k) rescue nil), v] }].freeze
|
61
|
+
|
62
|
+
# Create a new Augeas instance and return it.
|
63
|
+
#
|
64
|
+
# Use +:root+ as the filesystem root. If +:root+ is +nil+, use the value
|
65
|
+
# of the environment variable +AUGEAS_ROOT+. If that doesn't exist
|
66
|
+
# either, use "/".
|
67
|
+
#
|
68
|
+
# +:loadpath+ is a colon-spearated list of directories that modules
|
69
|
+
# should be searched in. This is in addition to the standard load path
|
70
|
+
# and the directories in +AUGEAS_LENS_LIB+
|
71
|
+
#
|
72
|
+
# The following flags can be specified in a hash. They all default to
|
73
|
+
# false and can be enabled by setting them to true
|
74
|
+
#
|
75
|
+
# :type_check - typecheck lenses (since it can be very expensive it is
|
76
|
+
# not done by default)
|
77
|
+
#
|
78
|
+
# :no_stdinc - do not use the builtin load path for modules
|
79
|
+
#
|
80
|
+
# :no_load - do not load the tree during the initialization phase
|
81
|
+
#
|
82
|
+
# :no_modl_autoload - do not load the tree during the initialization phase
|
83
|
+
#
|
84
|
+
# :enable_span - track the span in the input nodes
|
85
|
+
#
|
86
|
+
# :save_mode can be one of :backup, :newfile, :noop as explained below.
|
87
|
+
#
|
88
|
+
# :noop - make save a no-op process, just record what would have changed
|
89
|
+
#
|
90
|
+
# :backup - keep the original file with an .augsave extension
|
91
|
+
#
|
92
|
+
# :newfile - save changes into a file with an .augnew extension and
|
93
|
+
# do not overwrite the original file.
|
94
|
+
#
|
95
|
+
# When a block is given, the Augeas instance is passed as the only
|
96
|
+
# argument into the block and closed when the block exits.
|
97
|
+
# With no block, the Augeas instance is returned.
|
98
|
+
def self.create(opts={}, &block)
|
99
|
+
Augeas::Facade::create(opts, &block)
|
100
|
+
end
|
30
101
|
|
31
102
|
# Create a new Augeas instance and return it.
|
32
103
|
#
|
@@ -77,6 +148,18 @@ class Augeas
|
|
77
148
|
set_internal(path, nil)
|
78
149
|
end
|
79
150
|
|
151
|
+
# Clear multiple nodes values in one operation. Find or create a node matching +sub+
|
152
|
+
# by interpreting +sub+ as a path expression relative to each node matching
|
153
|
+
# +base+. If +sub+ is '.', the nodes matching +base+ will be modified.
|
154
|
+
def clearm(base, sub)
|
155
|
+
setm(base, sub, nil)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Create the +path+ with empty value if it doesn't exist
|
159
|
+
def touch(path)
|
160
|
+
set_internal(path, nil) if match(path).empty?
|
161
|
+
end
|
162
|
+
|
80
163
|
# Clear all transforms under <tt>/augeas/load</tt>. If +load+
|
81
164
|
# is called right after this, there will be no files
|
82
165
|
# under +/files+
|
@@ -98,6 +181,7 @@ class Augeas
|
|
98
181
|
excl = hash[:excl]
|
99
182
|
raise ArgumentError, "No lens specified" unless lens
|
100
183
|
raise ArgumentError, "No files to include" unless incl
|
184
|
+
lens = "#{lens}.lns" unless lens.include? '.'
|
101
185
|
name = lens.split(".")[0].sub("@", "") unless name
|
102
186
|
|
103
187
|
xfm = "/augeas/load/#{name}/"
|
@@ -116,4 +200,14 @@ class Augeas
|
|
116
200
|
raise Augeas::Error unless load
|
117
201
|
end
|
118
202
|
|
203
|
+
# Set path expression context to +path+ (in /augeas/context)
|
204
|
+
def context=(path)
|
205
|
+
set_internal('/augeas/context', path)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Get path expression context (from /augeas/context)
|
209
|
+
def context
|
210
|
+
get('/augeas/context')
|
211
|
+
end
|
212
|
+
|
119
213
|
end
|
data/tests/tc_augeas.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
|
-
|
3
|
+
unless defined?(TOPDIR)
|
4
|
+
TOPDIR = File::expand_path(File::join(File::dirname(__FILE__), ".."))
|
5
|
+
end
|
4
6
|
|
5
7
|
$:.unshift(File::join(TOPDIR, "lib"))
|
6
8
|
$:.unshift(File::join(TOPDIR, "ext", "augeas"))
|
@@ -84,7 +86,7 @@ class TestAugeas < Test::Unit::TestCase
|
|
84
86
|
:incl => [ "/etc/fstab" ],
|
85
87
|
:excl => [ "*~", "*.rpmnew" ])
|
86
88
|
}
|
87
|
-
aug.transform(:lens => "Inittab
|
89
|
+
aug.transform(:lens => "Inittab",
|
88
90
|
:incl => "/etc/inittab")
|
89
91
|
aug.transform(:lens => "Fstab.lns",
|
90
92
|
:incl => "/etc/fstab*",
|
@@ -195,6 +197,87 @@ class TestAugeas < Test::Unit::TestCase
|
|
195
197
|
assert_equal(29..40, span[:span])
|
196
198
|
end
|
197
199
|
|
200
|
+
def test_srun
|
201
|
+
aug = aug_open
|
202
|
+
|
203
|
+
path = "/files/etc/hosts/*[canonical='localhost.localdomain']/ipaddr"
|
204
|
+
r, out = aug.srun("get #{path}\n")
|
205
|
+
assert_equal(1, r)
|
206
|
+
assert_equal("#{path} = 127.0.0.1\n", out)
|
207
|
+
|
208
|
+
assert_equal(0, aug.srun(" ")[0])
|
209
|
+
assert_equal(-1, aug.srun("foo")[0])
|
210
|
+
assert_equal(-1, aug.srun("set")[0])
|
211
|
+
assert_equal(-2, aug.srun("quit")[0])
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_label
|
215
|
+
Augeas::open("/dev/null") do |aug|
|
216
|
+
assert_equal 'augeas', aug.label('/augeas')
|
217
|
+
assert_equal 'files', aug.label('/files')
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_rename
|
222
|
+
Augeas::open("/dev/null") do |aug|
|
223
|
+
assert_equal false, aug.rename('/files', 'invalid/label')
|
224
|
+
assert_equal 0, aug.rename('/nonexistent', 'label')
|
225
|
+
assert_equal ['/files'], aug.match('/files')
|
226
|
+
assert_equal 1, aug.rename('/files', 'label')
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_text_store_retrieve
|
231
|
+
Augeas::open("/dev/null") do |aug|
|
232
|
+
# text_store errors
|
233
|
+
assert_equal false, aug.text_store('Simplelines.lns', '/input', '/store')
|
234
|
+
|
235
|
+
# text_store
|
236
|
+
aug.set('/input', "line1\nline2\n")
|
237
|
+
assert aug.text_store('Simplelines.lns', '/input', '/store')
|
238
|
+
assert_equal 'line2', aug.get('/store/2')
|
239
|
+
|
240
|
+
# text_retrieve errors
|
241
|
+
assert_equal false, aug.text_retrieve('Simplelines.lns', '/unknown', '/store', '/output')
|
242
|
+
|
243
|
+
# text_retrieve
|
244
|
+
aug.set('/store/3', 'line3')
|
245
|
+
assert aug.text_retrieve('Simplelines.lns', '/input', '/store', '/output')
|
246
|
+
assert_equal "line1\nline2\nline3\n", aug.get('/output')
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_context
|
251
|
+
Augeas::open("/dev/null") do |aug|
|
252
|
+
aug.context = '/augeas'
|
253
|
+
assert_equal '/augeas', aug.get('/augeas/context')
|
254
|
+
assert_equal '/augeas', aug.get('context')
|
255
|
+
assert_equal '/augeas', aug.context
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_touch
|
260
|
+
Augeas::open("/dev/null") do |aug|
|
261
|
+
assert_equal [], aug.match('/foo')
|
262
|
+
aug.touch '/foo'
|
263
|
+
assert_equal ['/foo'], aug.match('/foo')
|
264
|
+
|
265
|
+
aug.set '/foo', 'bar'
|
266
|
+
aug.touch '/foo'
|
267
|
+
assert_equal 'bar', aug.get('/foo')
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_clearm
|
272
|
+
Augeas::open("/dev/null") do |aug|
|
273
|
+
aug.set('/foo/a', '1')
|
274
|
+
aug.set('/foo/b', '2')
|
275
|
+
aug.clearm('/foo', '*')
|
276
|
+
assert_nil aug.get('/foo/a')
|
277
|
+
assert_nil aug.get('/foo/b')
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
198
281
|
private
|
199
282
|
def aug_open(flags = Augeas::NONE)
|
200
283
|
if File::directory?(TST_ROOT)
|