ruby-augeas 0.4.1 → 0.5.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/NEWS CHANGED
@@ -1,3 +1,22 @@
1
+ 0.5.0 - 2013-03-XX
2
+ - add libxml2 headers and library to Makefile
3
+ - add libxml2-devel build req to rpm spec
4
+ - split out header, add memstream utils from Augeas
5
+ - integrate with Travis CI
6
+ - Takefile: add gem authors metadata
7
+ - Augeas::transform: add .lns suffix if a module name is passed
8
+ to match aug_transform behaviour
9
+ - add Augeas::clearm
10
+ - add Augeas::context and Augeas::context=
11
+ - add Augeas::label
12
+ - add Augeas::rename
13
+ - add Augeas::srun
14
+ - add Augeas::text_retrieve
15
+ - add Augeas::text_store
16
+
17
+ 0.4.1 - 2011-03-29
18
+ - remove object files from release tarball
19
+
1
20
  0.4.0 - 2011-03-25
2
21
  - set can now set multiple elements at once
3
22
  - expose aug_setm as Augeas#setm
@@ -15,4 +34,4 @@
15
34
 
16
35
  0.2.0 - 2008-08-26
17
36
  Details for this and earlier releases need to be extracted from the
18
- history of the git repo
37
+ history of the git repo
data/Rakefile CHANGED
@@ -9,13 +9,13 @@
9
9
  # Bryan Kearney <bkearney@redhat.com>
10
10
 
11
11
  require 'rake/clean'
12
- require 'rake/rdoctask'
12
+ require 'rdoc/task'
13
13
  require 'rake/testtask'
14
- require 'rake/gempackagetask'
14
+ require 'rubygems/package_task'
15
15
 
16
16
  PKG_NAME='ruby-augeas'
17
17
  GEM_NAME=PKG_NAME # we'd like 'augeas' but that makes RPM fail
18
- PKG_VERSION='0.4.1'
18
+ PKG_VERSION='0.5.0'
19
19
  EXT_CONF='ext/augeas/extconf.rb'
20
20
  MAKEFILE="ext/augeas/Makefile"
21
21
  AUGEAS_MODULE="ext/augeas/_augeas.so"
@@ -65,7 +65,7 @@ task :test => :build
65
65
  #
66
66
  # Generate the documentation
67
67
  #
68
- Rake::RDocTask.new do |rd|
68
+ RDoc::Task.new do |rd|
69
69
  rd.main = "README.rdoc"
70
70
  rd.rdoc_dir = "doc/site/api"
71
71
  rd.rdoc_files.include("README.rdoc", "ext/**/*.[ch]","lib/**/*.rb")
@@ -91,6 +91,7 @@ SPEC = Gem::Specification.new do |s|
91
91
  s.email = "augeas-devel@redhat.com"
92
92
  s.homepage = "http://augeas.net/"
93
93
  s.summary = "Ruby bindings for augeas"
94
+ s.authors = [ "Bryan Kearney", "David Lutterkort" ]
94
95
  s.files = PKG_FILES
95
96
  s.autorequire = "augeas"
96
97
  s.required_ruby_version = '>= 1.8.1'
@@ -98,7 +99,7 @@ SPEC = Gem::Specification.new do |s|
98
99
  s.description = "Provides bindings for augeas."
99
100
  end
100
101
 
101
- Rake::GemPackageTask.new(SPEC) do |pkg|
102
+ Gem::PackageTask.new(SPEC) do |pkg|
102
103
  pkg.need_tar = true
103
104
  pkg.need_zip = true
104
105
  end
@@ -130,3 +131,5 @@ end
130
131
  task :sync do |t|
131
132
  system "rsync -rav doc/site/ et:/var/www/sites/augeas.et.redhat.com/docs/ruby/"
132
133
  end
134
+
135
+ task :default => [:build, :test]
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * augeas.c: Ruby bindings for augeas
3
3
  *
4
- * Copyright (C) 2008 Red Hat Inc.
4
+ * Copyright (C) 2008-2011 Red Hat Inc.
5
5
  *
6
6
  * This library is free software; you can redistribute it and/or
7
7
  * modify it under the terms of the GNU Lesser General Public
@@ -19,14 +19,13 @@
19
19
  *
20
20
  * Author: Bryan Kearney <bkearney@redhat.com>
21
21
  */
22
+ #include "_augeas.h"
23
+
22
24
  #include <ruby.h>
23
25
  #include <augeas.h>
24
26
 
25
27
  static VALUE c_augeas;
26
28
 
27
- #define StringValueCStrOrNull(v) \
28
- NIL_P(v) ? NULL : StringValueCStr(v)
29
-
30
29
  static augeas *aug_handle(VALUE s) {
31
30
  augeas *aug;
32
31
 
@@ -383,6 +382,109 @@ VALUE augeas_span(VALUE s, VALUE path) {
383
382
  return result;
384
383
  }
385
384
 
385
+ /*
386
+ * call-seq:
387
+ * srun(COMMANDS) -> [int, String]
388
+ *
389
+ * Run one or more newline-separated commands, returning their output.
390
+ *
391
+ * Returns:
392
+ * an array where the first element is the number of executed commands on
393
+ * success, -1 on failure, and -2 if a 'quit' command was encountered.
394
+ * The second element is a string of the output from all commands.
395
+ */
396
+ VALUE augeas_srun(VALUE s, VALUE text) {
397
+ augeas *aug = aug_handle(s);
398
+ const char *ctext = StringValueCStr(text);
399
+
400
+ struct memstream ms;
401
+ __aug_init_memstream(&ms);
402
+
403
+ int r = aug_srun(aug, ms.stream, ctext);
404
+ __aug_close_memstream(&ms);
405
+
406
+ VALUE result = rb_ary_new();
407
+ rb_ary_push(result, INT2NUM(r));
408
+ rb_ary_push(result, rb_str_new2(ms.buf));
409
+
410
+ free(ms.buf);
411
+ return result;
412
+ }
413
+
414
+ /*
415
+ * call-seq:
416
+ * label(PATH) -> String
417
+ *
418
+ * Lookup the label associated with PATH
419
+ */
420
+ VALUE augeas_label(VALUE s, VALUE path) {
421
+ augeas *aug = aug_handle(s);
422
+ const char *cpath = StringValueCStr(path);
423
+ const char *label;
424
+
425
+ aug_label(aug, cpath, &label);
426
+ if (label != NULL) {
427
+ return rb_str_new(label, strlen(label)) ;
428
+ } else {
429
+ return Qnil;
430
+ }
431
+ }
432
+
433
+ /*
434
+ * call-seq:
435
+ * rename(SRC, LABEL) -> int
436
+ *
437
+ * Rename the label of all nodes matching SRC to LABEL.
438
+ *
439
+ * Returns +false+ if +aug_rename+ fails, and the number of nodes renamed
440
+ * on success.
441
+ */
442
+ VALUE augeas_rename(VALUE s, VALUE src, VALUE label) {
443
+ augeas *aug = aug_handle(s);
444
+ const char *csrc = StringValueCStr(src);
445
+ const char *clabel = StringValueCStr(label);
446
+ int r = aug_rename(aug, csrc, clabel);
447
+
448
+ return (r < 0) ? Qfalse : INT2NUM(r);
449
+ }
450
+
451
+ /*
452
+ * call-seq:
453
+ * text_store(LENS, NODE, PATH) -> boolean
454
+ *
455
+ * Use the value of node NODE as a string and transform it into a tree
456
+ * using the lens LENS and store it in the tree at PATH, which will be
457
+ * overwritten. PATH and NODE are path expressions.
458
+ */
459
+ VALUE augeas_text_store(VALUE s, VALUE lens, VALUE node, VALUE path) {
460
+ augeas *aug = aug_handle(s);
461
+ const char *clens = StringValueCStr(lens);
462
+ const char *cnode = StringValueCStr(node);
463
+ const char *cpath = StringValueCStr(path);
464
+ int r = aug_text_store(aug, clens, cnode, cpath);
465
+
466
+ return (r < 0) ? Qfalse : Qtrue;
467
+ }
468
+
469
+ /*
470
+ * call-seq:
471
+ * text_retrieve(LENS, NODE_IN, PATH, NODE_OUT) -> boolean
472
+ *
473
+ * Transform the tree at PATH into a string using lens LENS and store it in
474
+ * the node NODE_OUT, assuming the tree was initially generated using the
475
+ * value of node NODE_IN. PATH, NODE_IN, and NODE_OUT are path expressions.
476
+ */
477
+ VALUE augeas_text_retrieve(VALUE s, VALUE lens, VALUE node_in, VALUE path, VALUE node_out) {
478
+ augeas *aug = aug_handle(s);
479
+ const char *clens = StringValueCStr(lens);
480
+ const char *cnode_in = StringValueCStr(node_in);
481
+ const char *cpath = StringValueCStr(path);
482
+ const char *cnode_out = StringValueCStr(node_out);
483
+ int r = aug_text_retrieve(aug, clens, cnode_in, cpath, cnode_out);
484
+
485
+ return (r < 0) ? Qfalse : Qtrue;
486
+ }
487
+
386
488
  void Init__augeas() {
387
489
 
388
490
  /* Define the ruby class */
@@ -414,6 +516,8 @@ void Init__augeas() {
414
516
  DEF_AUG_ERR(ESYNTAX);
415
517
  DEF_AUG_ERR(ENOLENS);
416
518
  DEF_AUG_ERR(EMXFM);
519
+ DEF_AUG_ERR(ENOSPAN);
520
+ DEF_AUG_ERR(ECMDRUN);
417
521
  #undef DEF_AUG_ERR
418
522
 
419
523
  /* Define the methods */
@@ -433,6 +537,11 @@ void Init__augeas() {
433
537
  rb_define_method(c_augeas, "close", augeas_close, 0);
434
538
  rb_define_method(c_augeas, "error", augeas_error, 0);
435
539
  rb_define_method(c_augeas, "span", augeas_span, 1);
540
+ rb_define_method(c_augeas, "srun", augeas_srun, 1);
541
+ rb_define_method(c_augeas, "label", augeas_label, 1);
542
+ rb_define_method(c_augeas, "rename", augeas_rename, 2);
543
+ rb_define_method(c_augeas, "text_store", augeas_text_store, 3);
544
+ rb_define_method(c_augeas, "text_retrieve", augeas_text_retrieve, 4);
436
545
  }
437
546
 
438
547
  /*
@@ -0,0 +1,48 @@
1
+ /*
2
+ * augeas.h: internal headers for Augeas Ruby bindings
3
+ *
4
+ * Copyright (C) 2008-2011 Red Hat Inc.
5
+ *
6
+ * This library is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with this library; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ */
20
+
21
+ #include <ruby.h>
22
+
23
+ #ifndef _AUGEAS_H_
24
+ #define _AUGEAS_H_
25
+
26
+ #define StringValueCStrOrNull(v) \
27
+ NIL_P(v) ? NULL : StringValueCStr(v)
28
+
29
+ /* memstream support from Augeas internal.h */
30
+ struct memstream {
31
+ FILE *stream;
32
+ char *buf;
33
+ size_t size;
34
+ };
35
+
36
+ int __aug_init_memstream(struct memstream *ms);
37
+ int __aug_close_memstream(struct memstream *ms);
38
+
39
+ #endif
40
+
41
+ /*
42
+ * Local variables:
43
+ * indent-tabs-mode: nil
44
+ * c-indent-level: 4
45
+ * c-basic-offset: 4
46
+ * tab-width: 4
47
+ * End:
48
+ */
@@ -27,4 +27,8 @@ unless pkg_config("augeas")
27
27
  raise "augeas-devel not installed"
28
28
  end
29
29
 
30
+ unless pkg_config("libxml-2.0")
31
+ raise "libxml2-devel not installed"
32
+ end
33
+
30
34
  create_makefile(extension_name)
@@ -77,6 +77,18 @@ class Augeas
77
77
  set_internal(path, nil)
78
78
  end
79
79
 
80
+ # Clear multiple nodes values in one operation. Find or create a node matching +sub+
81
+ # by interpreting +sub+ as a path expression relative to each node matching
82
+ # +base+. If +sub+ is '.', the nodes matching +base+ will be modified.
83
+ def clearm(base, sub)
84
+ setm(base, sub, nil)
85
+ end
86
+
87
+ # Create the +path+ with empty value if it doesn't exist
88
+ def touch(path)
89
+ set_internal(path, nil) if match(path).empty?
90
+ end
91
+
80
92
  # Clear all transforms under <tt>/augeas/load</tt>. If +load+
81
93
  # is called right after this, there will be no files
82
94
  # under +/files+
@@ -98,6 +110,7 @@ class Augeas
98
110
  excl = hash[:excl]
99
111
  raise ArgumentError, "No lens specified" unless lens
100
112
  raise ArgumentError, "No files to include" unless incl
113
+ lens = "#{lens}.lns" unless lens.include? '.'
101
114
  name = lens.split(".")[0].sub("@", "") unless name
102
115
 
103
116
  xfm = "/augeas/load/#{name}/"
@@ -116,4 +129,14 @@ class Augeas
116
129
  raise Augeas::Error unless load
117
130
  end
118
131
 
132
+ # Set path expression context to +path+ (in /augeas/context)
133
+ def context=(path)
134
+ set_internal('/augeas/context', path)
135
+ end
136
+
137
+ # Get path expression context (from /augeas/context)
138
+ def context
139
+ get('/augeas/context')
140
+ end
141
+
119
142
  end
@@ -84,7 +84,7 @@ class TestAugeas < Test::Unit::TestCase
84
84
  :incl => [ "/etc/fstab" ],
85
85
  :excl => [ "*~", "*.rpmnew" ])
86
86
  }
87
- aug.transform(:lens => "Inittab.lns",
87
+ aug.transform(:lens => "Inittab",
88
88
  :incl => "/etc/inittab")
89
89
  aug.transform(:lens => "Fstab.lns",
90
90
  :incl => "/etc/fstab*",
@@ -195,6 +195,87 @@ class TestAugeas < Test::Unit::TestCase
195
195
  assert_equal(29..40, span[:span])
196
196
  end
197
197
 
198
+ def test_srun
199
+ aug = aug_open
200
+
201
+ path = "/files/etc/hosts/*[canonical='localhost.localdomain']/ipaddr"
202
+ r, out = aug.srun("get #{path}\n")
203
+ assert_equal(1, r)
204
+ assert_equal("#{path} = 127.0.0.1\n", out)
205
+
206
+ assert_equal(0, aug.srun(" ")[0])
207
+ assert_equal(-1, aug.srun("foo")[0])
208
+ assert_equal(-1, aug.srun("set")[0])
209
+ assert_equal(-2, aug.srun("quit")[0])
210
+ end
211
+
212
+ def test_label
213
+ Augeas::open("/dev/null") do |aug|
214
+ assert_equal 'augeas', aug.label('/augeas')
215
+ assert_equal 'files', aug.label('/files')
216
+ end
217
+ end
218
+
219
+ def test_rename
220
+ Augeas::open("/dev/null") do |aug|
221
+ assert_equal false, aug.rename('/files', 'invalid/label')
222
+ assert_equal 0, aug.rename('/nonexistent', 'label')
223
+ assert_equal ['/files'], aug.match('/files')
224
+ assert_equal 1, aug.rename('/files', 'label')
225
+ end
226
+ end
227
+
228
+ def test_text_store_retrieve
229
+ Augeas::open("/dev/null") do |aug|
230
+ # text_store errors
231
+ assert_equal false, aug.text_store('Simplelines.lns', '/input', '/store')
232
+
233
+ # text_store
234
+ aug.set('/input', "line1\nline2\n")
235
+ assert aug.text_store('Simplelines.lns', '/input', '/store')
236
+ assert_equal 'line2', aug.get('/store/2')
237
+
238
+ # text_retrieve errors
239
+ assert_equal false, aug.text_retrieve('Simplelines.lns', '/unknown', '/store', '/output')
240
+
241
+ # text_retrieve
242
+ aug.set('/store/3', 'line3')
243
+ assert aug.text_retrieve('Simplelines.lns', '/input', '/store', '/output')
244
+ assert_equal "line1\nline2\nline3\n", aug.get('/output')
245
+ end
246
+ end
247
+
248
+ def test_context
249
+ Augeas::open("/dev/null") do |aug|
250
+ aug.context = '/augeas'
251
+ assert_equal '/augeas', aug.get('/augeas/context')
252
+ assert_equal '/augeas', aug.get('context')
253
+ assert_equal '/augeas', aug.context
254
+ end
255
+ end
256
+
257
+ def test_touch
258
+ Augeas::open("/dev/null") do |aug|
259
+ assert_equal [], aug.match('/foo')
260
+ aug.touch '/foo'
261
+ assert_equal ['/foo'], aug.match('/foo')
262
+
263
+ aug.set '/foo', 'bar'
264
+ aug.touch '/foo'
265
+ assert_equal 'bar', aug.get('/foo')
266
+ end
267
+ end
268
+
269
+ def test_clearm
270
+ Augeas::open("/dev/null") do |aug|
271
+ aug.set('/foo/a', '1')
272
+ aug.set('/foo/b', '2')
273
+ aug.clearm('/foo', '*')
274
+ assert_nil aug.get('/foo/a')
275
+ assert_nil aug.get('/foo/b')
276
+ end
277
+ end
278
+
198
279
  private
199
280
  def aug_open(flags = Augeas::NONE)
200
281
  if File::directory?(TST_ROOT)
metadata CHANGED
@@ -1,80 +1,59 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruby-augeas
3
- version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 4
9
- - 1
10
- version: 0.4.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors: []
13
-
7
+ authors:
8
+ - Bryan Kearney
9
+ - David Lutterkort
14
10
  autorequire: augeas
15
11
  bindir: bin
16
12
  cert_chain: []
17
-
18
- date: 2011-03-29 00:00:00 -07:00
19
- default_executable:
13
+ date: 2013-03-12 00:00:00.000000000 Z
20
14
  dependencies: []
21
-
22
15
  description: Provides bindings for augeas.
23
16
  email: augeas-devel@redhat.com
24
17
  executables: []
25
-
26
- extensions:
18
+ extensions:
27
19
  - ext/augeas/extconf.rb
28
20
  extra_rdoc_files: []
29
-
30
- files:
21
+ files:
31
22
  - Rakefile
32
23
  - COPYING
33
24
  - README.rdoc
34
25
  - NEWS
35
26
  - ext/augeas/_augeas.c
27
+ - ext/augeas/_augeas.h
36
28
  - lib/augeas.rb
37
29
  - ext/augeas/extconf.rb
38
- - tests/tc_augeas.rb
39
- - tests/root/etc/hosts
40
30
  - tests/root/etc/group
31
+ - tests/root/etc/hosts
41
32
  - tests/root/etc/inittab
42
33
  - tests/root/etc/ssh/sshd_config
43
- has_rdoc: true
34
+ - tests/tc_augeas.rb
44
35
  homepage: http://augeas.net/
45
36
  licenses: []
46
-
47
37
  post_install_message:
48
38
  rdoc_options: []
49
-
50
- require_paths:
39
+ require_paths:
51
40
  - lib
52
- required_ruby_version: !ruby/object:Gem::Requirement
41
+ required_ruby_version: !ruby/object:Gem::Requirement
53
42
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 53
58
- segments:
59
- - 1
60
- - 8
61
- - 1
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
62
46
  version: 1.8.1
63
- required_rubygems_version: !ruby/object:Gem::Requirement
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
48
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- hash: 3
69
- segments:
70
- - 0
71
- version: "0"
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
72
53
  requirements: []
73
-
74
54
  rubyforge_project:
75
- rubygems_version: 1.3.7
55
+ rubygems_version: 1.8.23
76
56
  signing_key:
77
57
  specification_version: 3
78
58
  summary: Ruby bindings for augeas
79
59
  test_files: []
80
-