Skip to content

Commit

Permalink
Expose changes in Augeas 1.0.0 release
Browse files Browse the repository at this point in the history
  * ext/augeas/_augeas.c: add Augeas#label, Augeas#rename, Augeas#text_retrieve
    and Augeas#text_store
  * lib/augeas.rb: add ".lns" suffix if a module name is passed to
    Augeas#transform to match aug_transform behaviour;
    add Augeas#clearm, #touch to mirror aug_srun commands;
    add Augeas#context= and #context to access /augeas/context
  • Loading branch information
Dominic Cleal committed Dec 23, 2012
1 parent 9eca123 commit 9025d88
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 1 deletion.
78 changes: 78 additions & 0 deletions ext/augeas/_augeas.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,80 @@ VALUE augeas_srun(VALUE s, VALUE text) {
return result;
}

/*
* call-seq:
* label(PATH) -> String
*
* Lookup the label associated with PATH
*/
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;
}
}

/*
* call-seq:
* rename(SRC, LABEL) -> int
*
* Rename the label of all nodes matching SRC to LABEL.
*
* Returns +false+ if +aug_rename+ fails, and the number of nodes renamed
* on success.
*/
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);
}

/*
* call-seq:
* 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.
*/
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;
}

/*
* call-seq:
* 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.
*/
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;
}

void Init__augeas() {

/* Define the ruby class */
Expand Down Expand Up @@ -464,6 +538,10 @@ void Init__augeas() {
rb_define_method(c_augeas, "error", augeas_error, 0);
rb_define_method(c_augeas, "span", augeas_span, 1);
rb_define_method(c_augeas, "srun", augeas_srun, 1);
rb_define_method(c_augeas, "label", augeas_label, 1);
rb_define_method(c_augeas, "rename", augeas_rename, 2);
rb_define_method(c_augeas, "text_store", augeas_text_store, 3);
rb_define_method(c_augeas, "text_retrieve", augeas_text_retrieve, 4);
}

/*
Expand Down
23 changes: 23 additions & 0 deletions lib/augeas.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ def clear(path)
set_internal(path, nil)
end

# Clear multiple nodes values in one operation. Find or create a node matching +sub+
# by interpreting +sub+ as a path expression relative to each node matching
# +base+. If +sub+ is '.', the nodes matching +base+ will be modified.
def clearm(base, sub)
setm(base, sub, nil)
end

# Create the +path+ with empty value if it doesn't exist
def touch(path)
set_internal(path, nil) if match(path).empty?
end

# Clear all transforms under <tt>/augeas/load</tt>. If +load+
# is called right after this, there will be no files
# under +/files+
Expand All @@ -98,6 +110,7 @@ def transform(hash)
excl = hash[:excl]
raise ArgumentError, "No lens specified" unless lens
raise ArgumentError, "No files to include" unless incl
lens = "#{lens}.lns" unless lens.include? '.'
name = lens.split(".")[0].sub("@", "") unless name

xfm = "/augeas/load/#{name}/"
Expand All @@ -116,4 +129,14 @@ def load!
raise Augeas::Error unless load
end

# Set path expression context to +path+ (in /augeas/context)
def context=(path)
set_internal('/augeas/context', path)
end

# Get path expression context (from /augeas/context)
def context
get('/augeas/context')
end

end
69 changes: 68 additions & 1 deletion tests/tc_augeas.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_transform
:incl => [ "/etc/fstab" ],
:excl => [ "*~", "*.rpmnew" ])
}
aug.transform(:lens => "Inittab.lns",
aug.transform(:lens => "Inittab",
:incl => "/etc/inittab")
aug.transform(:lens => "Fstab.lns",
:incl => "/etc/fstab*",
Expand Down Expand Up @@ -209,6 +209,73 @@ def test_srun
assert_equal(-2, aug.srun("quit")[0])
end

def test_label
Augeas::open("/dev/null") do |aug|
assert_equal 'augeas', aug.label('/augeas')
assert_equal 'files', aug.label('/files')
end
end

def test_rename
Augeas::open("/dev/null") do |aug|
assert_equal false, aug.rename('/files', 'invalid/label')
assert_equal 0, aug.rename('/nonexistent', 'label')
assert_equal ['/files'], aug.match('/files')
assert_equal 1, aug.rename('/files', 'label')
end
end

def test_text_store_retrieve
Augeas::open("/dev/null") do |aug|
# text_store errors
assert_equal false, aug.text_store('Simplelines.lns', '/input', '/store')

# text_store
aug.set('/input', "line1\nline2\n")
assert aug.text_store('Simplelines.lns', '/input', '/store')
assert_equal 'line2', aug.get('/store/2')

# text_retrieve errors
assert_equal false, aug.text_retrieve('Simplelines.lns', '/unknown', '/store', '/output')

# text_retrieve
aug.set('/store/3', 'line3')
assert aug.text_retrieve('Simplelines.lns', '/input', '/store', '/output')
assert_equal "line1\nline2\nline3\n", aug.get('/output')
end
end

def test_context
Augeas::open("/dev/null") do |aug|
aug.context = '/augeas'
assert_equal '/augeas', aug.get('/augeas/context')
assert_equal '/augeas', aug.get('context')
assert_equal '/augeas', aug.context
end
end

def test_touch
Augeas::open("/dev/null") do |aug|
assert_equal [], aug.match('/foo')
aug.touch '/foo'
assert_equal ['/foo'], aug.match('/foo')

aug.set '/foo', 'bar'
aug.touch '/foo'
assert_equal 'bar', aug.get('/foo')
end
end

def test_clearm
Augeas::open("/dev/null") do |aug|
aug.set('/foo/a', '1')
aug.set('/foo/b', '2')
aug.clearm('/foo', '*')
assert_nil aug.get('/foo/a')
assert_nil aug.get('/foo/b')
end
end

private
def aug_open(flags = Augeas::NONE)
if File::directory?(TST_ROOT)
Expand Down

0 comments on commit 9025d88

Please sign in to comment.