Class: Augeas::Facade

Inherits:
Object
  • Object
show all
Defined in:
lib/augeas/facade.rb,
ext/augeas/_augeas.c

Overview

Wrapper class for the augeas library.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.create(opts = {}, &block) ⇒ Object



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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/augeas/facade.rb', line 33

def self.create(opts={}, &block)
  # aug_flags is a bitmask in the underlying library, we add all the
  # values of the flags which were set to true to the default value
  # Augeas::NONE (which is 0)
  aug_flags = defined?(Augeas::NO_ERR_CLOSE) ? Augeas::NO_ERR_CLOSE : Augeas::NONE

  flags = {
    :type_check => Augeas::TYPE_CHECK,
    :no_stdinc => Augeas::NO_STDINC,
    :no_load => Augeas::NO_LOAD,
    :no_modl_autoload => Augeas::NO_MODL_AUTOLOAD,
    :enable_span => Augeas::ENABLE_SPAN
  }
  save_modes = {
    :backup => Augeas::SAVE_BACKUP,
    :newfile => Augeas::SAVE_NEWFILE,
    :noop => Augeas::SAVE_NOOP
  }
  opts.each_key do |key|
    if flags.key? key
      aug_flags |= flags[key]
    elsif key == :save_mode
      if save_modes[opts[:save_mode]]
        aug_flags |= save_modes[opts[:save_mode]]
      else
        raise ArgumentError, "Invalid save mode #{opts[:save_mode]}."
      end
    elsif key != :root && key != :loadpath
      raise ArgumentError, "Unknown argument #{key}."
    end
  end

  aug = Augeas::Facade::open3(opts[:root], opts[:loadpath], aug_flags)

  begin
    aug.send(:raise_last_error)
  rescue
    aug.close
    raise
  end

  if block_given?
    begin
      yield aug
    ensure
      aug.close
    end
  else
    return aug
  end
end

.open3(r, l, f) ⇒ Object

Define methods to support the 'new' API in Augeas::Facade



362
363
364
# File 'ext/augeas/_augeas.c', line 362

VALUE facade_init(VALUE m, VALUE r, VALUE l, VALUE f) {
    return init(c_facade, m, r, l, f);
}

Instance Method Details

#defnode(NAME, EXPR, VALUE) ⇒ Boolean

Define a variable NAME whose value is the result of evaluating EXPR, which must be non-NULL and evaluate to a nodeset. If a variable NAME already exists, its name will be replaced with the result of evaluating EXPR.

If EXPR evaluates to an empty nodeset, a node is created, equivalent to calling AUG_SET(AUG, EXPR, VALUE) and NAME will be the nodeset containing that single node.

Returns false if aug_defnode fails, and the number of nodes in the nodeset on success.

Returns:

  • (Boolean)


332
333
334
335
336
337
338
339
340
341
342
343
# File 'ext/augeas/_augeas.c', line 332

VALUE augeas_defnode(VALUE s, VALUE name, VALUE expr, VALUE value) {
    augeas *aug = aug_handle(s);
    const char *cname = StringValueCStr(name);
    const char *cexpr = StringValueCStrOrNull(expr);
    const char *cvalue = StringValueCStrOrNull(value);

    /* FIXME: Figure out a way to return created, maybe accept a block
       that gets run when created == 1 ? */
    int r = aug_defnode(aug, cname, cexpr, cvalue, NULL);

    return (r < 0) ? Qfalse : INT2NUM(r);
}

#defvar(NAME, EXPR) ⇒ Boolean

Define a variable NAME whose value is the result of evaluating EXPR. If a variable NAME already exists, its name will be replaced with the result of evaluating EXPR.

If EXPR is NULL, the variable NAME will be removed if it is defined.

Returns:

  • (Boolean)


306
307
308
309
310
311
312
313
314
# File 'ext/augeas/_augeas.c', line 306

VALUE augeas_defvar(VALUE s, VALUE name, VALUE expr) {
    augeas *aug = aug_handle(s);
    const char *cname = StringValueCStr(name);
    const char *cexpr = StringValueCStrOrNull(expr);

    int r = aug_defvar(aug, cname, cexpr);

    return (r < 0) ? Qfalse : Qtrue;
}

#exists(PATH) ⇒ Boolean

Return true if there is an entry for this path, false otherwise

Returns:

  • (Boolean)


93
94
95
96
97
98
99
# File 'ext/augeas/_augeas.c', line 93

VALUE augeas_exists(VALUE s, VALUE path) {
    augeas *aug = aug_handle(s);
    const char *cpath = StringValueCStr(path);
    int ret = aug_get(aug, cpath, NULL);

    return (ret == 1) ? Qtrue : Qfalse;
}

#get(PATH) ⇒ String

Lookup the value associated with PATH

Returns:

  • (String)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'ext/augeas/_augeas.c', line 51

VALUE augeas_get(VALUE s, VALUE path) {
    augeas *aug = aug_handle(s);
    const char *cpath = StringValueCStr(path);
    const char *value = NULL;

    int r = aug_get(aug, cpath, &value);
    /* There used to be a bug in Augeas that would make it not properly set
     * VALUE to NULL when PATH was invalid. We check RETVAL, too, to avoid
     * running into that */
    if (r == 1 && value != NULL) {
        return rb_str_new(value, strlen(value)) ;
    } else {
        return Qnil;
    }
}

#insert(PATH, LABEL, BEFORE) ⇒ Integer

Make LABEL a sibling of PATH by inserting it directly before or after PATH. The boolean BEFORE determines if LABEL is inserted before or after PATH.

Returns:

  • (Integer)


153
154
155
156
157
158
159
160
# File 'ext/augeas/_augeas.c', line 153

VALUE augeas_insert(VALUE s, VALUE path, VALUE label, VALUE before) {
    augeas *aug = aug_handle(s);
    const char *cpath = StringValueCStr(path) ;
    const char *clabel = StringValueCStr(label) ;

    int callValue = aug_insert(aug, cpath, clabel, RTEST(before));
    return INT2FIX(callValue) ;
}

#label(PATH) ⇒ String

Lookup the label associated with PATH

Returns:

  • (String)


489
490
491
492
493
494
495
496
497
498
499
500
# File 'ext/augeas/_augeas.c', line 489

VALUE augeas_label(VALUE s, VALUE path) {
    augeas *aug = aug_handle(s);
    const char *cpath = StringValueCStr(path);
    const char *label;

    aug_label(aug, cpath, &label);
    if (label != NULL) {
        return rb_str_new(label, strlen(label)) ;
    } else {
        return Qnil;
    }
}

#load ⇒ Boolean

Load files from disk according to the transforms under /augeas/load

Returns:

  • (Boolean)


282
283
284
285
286
287
288
289
290
291
292
293
# File 'ext/augeas/_augeas.c', line 282

VALUE augeas_load(VALUE s) {
    augeas *aug = aug_handle(s);
    int callValue = aug_load(aug);
    VALUE returnValue ;

    if (callValue == 0)
        returnValue = Qtrue ;
    else
        returnValue = Qfalse ;

    return returnValue ;
}

#match(PATH) ⇒ Array

Return all the paths that match the path expression PATH as an aray of strings. Returns an empty array if no paths were found.

Returns:

  • (Array)


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'ext/augeas/_augeas.c', line 232

VALUE facade_match(VALUE s, VALUE p) {
    augeas *aug = aug_handle(s);
    const char *path = StringValueCStr(p);
    char **matches = NULL;
    int cnt, i;
    VALUE result;

    cnt = aug_match(aug, path, &matches) ;
    if (cnt < 0)
        return -1;

    result = rb_ary_new();
    for (i = 0; i < cnt; i++) {
        rb_ary_push(result, rb_str_new(matches[i], strlen(matches[i])));
        free(matches[i]) ;
    }
    free (matches) ;

    return result ;
}

#mv(SRC, DST) ⇒ Integer

Move the node SRC to DST. SRC must match exactly one node in the tree. DST must either match exactly one node in the tree, or may not exist yet. If DST exists already, it and all its descendants are deleted. If DST does not exist yet, it and all its missing ancestors are created.

Returns:

  • (Integer)


172
173
174
175
176
177
178
179
# File 'ext/augeas/_augeas.c', line 172

VALUE augeas_mv(VALUE s, VALUE src, VALUE dst) {
    augeas *aug = aug_handle(s);
    const char *csrc = StringValueCStr(src);
    const char *cdst = StringValueCStr(dst);
    int r = aug_mv(aug, csrc, cdst);

    return INT2FIX(r);
}

#rename(SRC, LABEL) ⇒ Integer

Rename the label of all nodes matching SRC to LABEL.

Returns false if aug_rename fails, and the number of nodes renamed on success.

Returns:

  • (Integer)


511
512
513
514
515
516
517
518
# File 'ext/augeas/_augeas.c', line 511

VALUE augeas_rename(VALUE s, VALUE src, VALUE label) {
    augeas *aug = aug_handle(s);
    const char *csrc = StringValueCStr(src);
    const char *clabel = StringValueCStr(label);
    int r = aug_rename(aug, csrc, clabel);

    return (r < 0) ? Qfalse : INT2NUM(r);
}

#rm(PATH) ⇒ Integer

Remove path and all its children. Returns the number of entries removed

Returns:

  • (Integer)


187
188
189
190
191
192
193
# File 'ext/augeas/_augeas.c', line 187

VALUE augeas_rm(VALUE s, VALUE path) {
    augeas *aug = aug_handle(s);
    const char *cpath = StringValueCStr(path) ;

    int callValue = aug_rm(aug, cpath) ;
    return INT2FIX(callValue) ;
}

#save ⇒ Integer

Write all pending changes to disk

Returns:

  • (Integer)


271
272
273
274
# File 'ext/augeas/_augeas.c', line 271

VALUE facade_save(VALUE s) {
    augeas *aug = aug_handle(s);
    return INT2FIX(aug_save(aug));
}

#augeas_set(path, value) ⇒ Object



123
124
125
# File 'ext/augeas/_augeas.c', line 123

VALUE facade_set(VALUE s, VALUE path, VALUE value) {
    return INT2FIX(set(s, path, value));
}

#setm(BASE, SUB, VALUE) ⇒ Boolean

Set multiple nodes in one operation. Find or create a node matching SUB by interpreting SUB as a path expression relative to each node matching BASE. SUB may be NULL, in which case all the nodes matching BASE will be modified.

Returns:

  • (Boolean)


136
137
138
139
140
141
142
143
144
# File 'ext/augeas/_augeas.c', line 136

VALUE augeas_setm(VALUE s, VALUE base, VALUE sub, VALUE value) {
    augeas *aug = aug_handle(s);
    const char *cbase = StringValueCStr(base) ;
    const char *csub = StringValueCStrOrNull(sub) ;
    const char *cvalue = StringValueCStrOrNull(value) ;

    int callValue = aug_setm(aug, cbase, csub, cvalue) ;
    return INT2FIX(callValue);
}

#augeas_span(path) ⇒ Object



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# File 'ext/augeas/_augeas.c', line 424

VALUE augeas_span(VALUE s, VALUE path) {
    augeas *aug = aug_handle(s);
    char *cpath = StringValueCStr(path);
    char *filename = NULL;
    unsigned int label_start, label_end, value_start, value_end,
        span_start, span_end;
    int r;
    VALUE result;

    r = aug_span(aug, cpath,
                 &filename,
                 &label_start, &label_end,
                 &value_start, &value_end,
                 &span_start, &span_end);

    result = rb_hash_new();

    if (r == 0) {
        hash_set(result, "filename", rb_str_new2(filename));
        hash_set_range(result, "label", label_start, label_end);
        hash_set_range(result, "value", value_start, value_end);
        hash_set_range(result, "span", span_start, span_end);
    }

    free(filename);

    return result;
}

#srun(COMMANDS) ⇒ Array, String

Run one or more newline-separated commands, returning their output.

Returns: an array where the first element is the number of executed commands on success, -1 on failure, and -2 if a 'quit' command was encountered. The second element is a string of the output from all commands.

Returns ].

Returns:

  • (Array, String) —

    ]



464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'ext/augeas/_augeas.c', line 464

VALUE augeas_srun(VALUE s, VALUE text) {
    augeas *aug = aug_handle(s);
    const char *ctext = StringValueCStr(text);
    int r;
    VALUE result;
    struct memstream ms;
    __aug_init_memstream(&ms);

    r = aug_srun(aug, ms.stream, ctext);
    __aug_close_memstream(&ms);

    result = rb_ary_new();
    rb_ary_push(result, INT2NUM(r));
    rb_ary_push(result, rb_str_new2(ms.buf));

    free(ms.buf);
    return result;
}

#text_retrieve(LENS, NODE_IN, PATH, NODE_OUT) ⇒ Boolean

Transform the tree at PATH into a string using lens LENS and store it in the node NODE_OUT, assuming the tree was initially generated using the value of node NODE_IN. PATH, NODE_IN, and NODE_OUT are path expressions.

Returns:

  • (Boolean)


546
547
548
549
550
551
552
553
554
555
# File 'ext/augeas/_augeas.c', line 546

VALUE augeas_text_retrieve(VALUE s, VALUE lens, VALUE node_in, VALUE path, VALUE node_out) {
    augeas *aug = aug_handle(s);
    const char *clens = StringValueCStr(lens);
    const char *cnode_in = StringValueCStr(node_in);
    const char *cpath = StringValueCStr(path);
    const char *cnode_out = StringValueCStr(node_out);
    int r = aug_text_retrieve(aug, clens, cnode_in, cpath, cnode_out);

    return (r < 0) ? Qfalse : Qtrue;
}

#text_store(LENS, NODE, PATH) ⇒ Boolean

Use the value of node NODE as a string and transform it into a tree using the lens LENS and store it in the tree at PATH, which will be overwritten. PATH and NODE are path expressions.

Returns:

  • (Boolean)


528
529
530
531
532
533
534
535
536
# File 'ext/augeas/_augeas.c', line 528

VALUE augeas_text_store(VALUE s, VALUE lens, VALUE node, VALUE path) {
    augeas *aug = aug_handle(s);
    const char *clens = StringValueCStr(lens);
    const char *cnode = StringValueCStr(node);
    const char *cpath = StringValueCStr(path);
    int r = aug_text_store(aug, clens, cnode, cpath);

    return (r < 0) ? Qfalse : Qtrue;
}

#clear(path) ⇒ Object

Clear the path, i.e. make its value nil



150
151
152
# File 'lib/augeas/facade.rb', line 150

def clear(path)
  augeas_set(path, nil)
end

#clear_transforms ⇒ Object

Clear all transforms under /augeas/load. If load is called right after this, there will be no files under /files



181
182
183
# File 'lib/augeas/facade.rb', line 181

def clear_transforms
  rm("/augeas/load/*")
end

#clearm(path, sub) ⇒ Object



198
199
200
# File 'lib/augeas/facade.rb', line 198

def clearm(path, sub)
  setm(path, sub, nil)
end

#close ⇒ Object

The close and error methods as used unchanged in the ruby bindings



366
367
368
369
370
371
372
373
# File 'ext/augeas/_augeas.c', line 366

VALUE augeas_close (VALUE s) {
    augeas *aug = aug_handle(s);

    aug_close(aug);
    DATA_PTR(s) = NULL;

    return Qnil;
}

#context ⇒ Object

Get path expression context (from /augeas/context)



294
295
296
# File 'lib/augeas/facade.rb', line 294

def context
  get('/augeas/context')
end

#context=(path) ⇒ Object

Set path expression context to path (in /augeas/context)



289
290
291
# File 'lib/augeas/facade.rb', line 289

def context=(path)
  set('/augeas/context', path)
end

#defnode(name, expr, value = nil) ⇒ Object

Define the variable name to the result of evaluating expr, which must be a nodeset. If no node matching expr exists yet, one is created and name will refer to it. When a node is created and value is given, the new node's value is set to value.



145
146
147
# File 'lib/augeas/facade.rb', line 145

def defnode(name, expr, value=nil)
  run_command :augeas_defnode, name, expr, value
end

#defvar(name, expr) ⇒ Object

Evaluate expr and set the variable name to the resulting nodeset. The variable can be used in path expressions as $name. Note that expr is evaluated when the variable is defined, not when it is used.



137
138
139
# File 'lib/augeas/facade.rb', line 137

def defvar(name, expr)
  run_command :augeas_defvar, name, expr
end

#error ⇒ Object

Retrieve details about the last error encountered and return those details in a HASH with the following entries:

  • :code error code from aug_error
  • :message error message from aug_error_message
  • :minor minor error message from aug_minor_error_message
  • :details error details from aug_error_details


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'ext/augeas/_augeas.c', line 390

VALUE augeas_error(VALUE s) {
    augeas *aug = aug_handle(s);
    int code;
    const char *msg;
    VALUE result;

    result = rb_hash_new();

    code = aug_error(aug);
    hash_set(result, "code", INT2NUM(code));

    msg = aug_error_message(aug);
    if (msg != NULL)
        hash_set(result, "message", rb_str_new2(msg));

    msg = aug_error_minor_message(aug);
    if (msg != NULL)
        hash_set(result, "minor", rb_str_new2(msg));

    msg = aug_error_details(aug);
    if (msg != NULL)
        hash_set(result, "details", rb_str_new2(msg));

    return result;
}

#exists(path) ⇒ Object

Return true if there is an entry for this path, false otherwise



91
92
93
# File 'lib/augeas/facade.rb', line 91

def exists(path)
  run_command :augeas_exists, path
end

#get(path) ⇒ Object

Get the value associated with path.



86
87
88
# File 'lib/augeas/facade.rb', line 86

def get(path)
  run_command :augeas_get, path
end

#insert(path, label, before) ⇒ Object

Make label a sibling of path by inserting it directly before or after path. The boolean before determines if label is inserted before or after path.



284
285
286
# File 'lib/augeas/facade.rb', line 284

def insert(path, label, before)
  run_command :augeas_insert, path, label, before
end

#label(path) ⇒ Object

Lookup the label associated with path Raises Augeas::NoMatchError if the path node does not exist



255
256
257
# File 'lib/augeas/facade.rb', line 255

def label(path)
  run_command :augeas_label, path
end

#load ⇒ Object

Load files according to the transforms in /augeas/load or those defined via transform. A transform Foo is represented with a subtree /augeas/load/Foo. Underneath /augeas/load/Foo, one node labeled 'lens' must exist, whose value is the fully qualified name of a lens, for example 'Foo.lns', and multiple nodes 'incl' and 'excl' whose values are globs that determine which files are transformed by that lens. It is an error if one file can be processed by multiple transforms.



210
211
212
213
214
215
216
217
218
219
# File 'lib/augeas/facade.rb', line 210

def load
  begin
    run_command :augeas_load
  rescue Augeas::CommandExecutionError => e
    raise e, "Loading failed. Search the augeas tree in /augeas//error"+
      "for the actual errors."
  end

  nil
end

#match(path) ⇒ Object

Return an Array of all the paths that match the path expression path

Returns an empty Array if no paths were found. Raises an Augeas::InvalidPathError when the path is invalid.



124
125
126
# File 'lib/augeas/facade.rb', line 124

def match(path)
  run_command :augeas_match, path
end

#mv(src, dst) ⇒ Object

Move node src to dst. src must match exactly one node in the tree. dst must either match exactly one node in the tree, or may not exist yet. If dst exists already, it and all its descendants are deleted. If dst does not exist yet, it and all its missing ancestors are created.

Raises Augeas::NoMatchError if the src node does not exist Raises Augeas::MultipleMatchesError if there were multiple matches in src Raises Augeas::DescendantError if the dst node is a descendant of the src node.



232
233
234
# File 'lib/augeas/facade.rb', line 232

def mv(src, dst)
  run_command :augeas_mv, src, dst
end

#rename(path, label) ⇒ Object

Rename the label of all nodes matching path to label Raises Augeas::NoMatchError if the path node does not exist Raises Augeas::InvalidLabelError if label is invalid



262
263
264
# File 'lib/augeas/facade.rb', line 262

def rename(path, label)
  run_command :augeas_rename, path, label
end

#rm(path) ⇒ Object

Remove all nodes matching path expression path and all their children. Raises an Augeas::InvalidPathError when the path is invalid.



116
117
118
# File 'lib/augeas/facade.rb', line 116

def rm(path)
  run_command :augeas_rm, path
end

#save ⇒ Object

Write all pending changes to disk. Raises Augeas::CommandExecutionError if saving fails.



187
188
189
190
191
192
193
194
195
196
# File 'lib/augeas/facade.rb', line 187

def save
  begin
    run_command :augeas_save
  rescue Augeas::CommandExecutionError => e
    raise e, 'Saving failed. Search the augeas tree in /augeas//error ' <<
      'for the actual errors.'
  end

  nil
end

#set(path, *values) ⇒ Object

Set one or multiple elements to path. Multiple elements are mainly sensible with a path like .../array, since this will append all elements.



98
99
100
# File 'lib/augeas/facade.rb', line 98

def set(path, *values)
  values.flatten.each { |v| run_command :augeas_set, path, v }
end

#setm(base, sub, value) ⇒ Object

base the base node sub the subtree relative to the base value the value for the nodes



109
110
111
# File 'lib/augeas/facade.rb', line 109

def setm(base, sub, value)
  run_command :augeas_setm, base, sub, value
end

#span(path) ⇒ Object

Get the filename, label and value position in the text of this node

Raises Augeas::NoMatchError if the node could not be found Raises Augeas::NoSpanInfo if the node associated with path doesn't belong to a file or doesn't exist



241
242
243
# File 'lib/augeas/facade.rb', line 241

def span(path)
  run_command :augeas_span, path
end

#srun(text) ⇒ Object

Run one or more newline-separated commands specified by text, returns an array of [successful_commands_number, output] or [-2, output] in case 'quit' command has been encountered. Raises Augeas::CommandExecutionError if gets an invalid command



249
250
251
# File 'lib/augeas/facade.rb', line 249

def srun(text)
  run_command(:augeas_srun, text)
end

#text_retrieve(lens, node_in, path, node_out) ⇒ Object

Transform the tree at path into a string lens lens and store it in the node node_out, assuming the tree was initially generated using the value of node node_in. path, node_in and node_out are path expressions.



276
277
278
# File 'lib/augeas/facade.rb', line 276

def text_retrieve(lens, node_in, path, node_out)
  run_command :augeas_text_retrieve, lens, node_in, path, node_out
end

#text_store(lens, node, path) ⇒ Object

Use the value of node node as a string and transform it into a tree using the lens lens and store it in the tree at path, which will be overwritten. path and node are path expressions.



269
270
271
# File 'lib/augeas/facade.rb', line 269

def text_store(lens, node, path)
  run_command :augeas_text_store, lens, node, path
end

#touch(path) ⇒ Object

Create the path with empty value if it doesn't exist



129
130
131
# File 'lib/augeas/facade.rb', line 129

def touch(path)
  set(path, nil) if match(path).empty?
end

#transform(hash) ⇒ Object

Add a transform under /augeas/load

The HASH can contain the following entries

  • :lens - the name of the lens to use
  • :name - a unique name; use the module name of the LENS when omitted
  • :incl - a list of glob patterns for the files to transform
  • :excl - a list of the glob patterns to remove from the list that matches :incl

Raises:

  • (ArgumentError)


163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/augeas/facade.rb', line 163

def transform(hash)
  lens = hash[:lens]
  name = hash[:name]
  incl = hash[:incl]
  excl = hash[:excl]
  raise ArgumentError, "No lens specified" unless lens
  raise ArgumentError, "No files to include" unless incl
  name = lens.split(".")[0].sub("@", "") unless name

  xfm = "/augeas/load/#{name}/"
  set(xfm + "lens", lens)
  set(xfm + "incl[last()+1]", incl)
  set(xfm + "excl[last()+1]", excl) if excl
end