treequel 1.7.0 → 1.7.1

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.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,12 @@
1
+ == v1.7.1 [2011-11-28] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ - Modified filter expressions to eliminate unnecessary ORing
4
+ - Efficiency fixes for Treequel::Model#modifications (delete/add -> replace)
5
+ - Fixing missing DN attribute/s on Treequel::Model objects created via
6
+ attribute traversal methods.
7
+ - Log errors added during validation at ERROR level
8
+
9
+
1
10
  == v1.7.0 [2011-11-09] Michael Granger <ged@FaerieMUD.org>
2
11
 
3
12
  - Treat Treequel::Model#[]= with a nil value on a SINGLE-VALUE
@@ -12,29 +12,6 @@ It's inspired by and modeled after [Sequel](http://sequel.rubyforge.org/), a
12
12
  kick-ass database library.
13
13
 
14
14
 
15
- == Examples
16
-
17
- Here are a few short examples to whet your appetite:
18
-
19
- # Connect to the directory at the specified URL
20
- dir = Treequel.directory( 'ldap://ldap.company.com/dc=company,dc=com' )
21
-
22
- # Get a list of email addresses of every person in the directory (as
23
- # long as people are under ou=people)
24
- dir.ou( :people ).filter( :mail ).map( :mail ).flatten
25
-
26
- # Get a list of all IP addresses for all hosts in any ou=hosts group
27
- # in the whole directory:
28
- dir.filter( :ou => :hosts ).collection.filter( :ipHostNumber ).
29
- map( :ipHostNumber ).flatten
30
-
31
- # Get all people in the directory in the form of a hash of names
32
- # keyed by email addresses
33
- dir.ou( :people ).filter( :mail ).to_hash( :mail, :cn )
34
-
35
- More elaborate examples of real-world usage can be found
36
- {in the examples/ directory}[http://deveiate.org/projects/Treequel/browser/examples]
37
- in the distribution.
38
15
 
39
16
 
40
17
  == Contributing
@@ -26,10 +26,10 @@ end
26
26
  module Treequel
27
27
 
28
28
  # Library version
29
- VERSION = '1.7.0'
29
+ VERSION = '1.7.1'
30
30
 
31
31
  # VCS revision
32
- REVISION = %q$Revision: c5b83ddad969 $
32
+ REVISION = %q$Revision: d2ba344f87e8 $
33
33
 
34
34
  # Common paths for ldap.conf
35
35
  COMMON_LDAP_CONF_PATHS = %w[
@@ -499,13 +499,18 @@ class Treequel::Filter
499
499
  filterlist = expression.collect do |key, expr|
500
500
  Treequel.logger.debug " adding %p => %p to the filter list" % [ key, expr ]
501
501
  if expr.respond_to?( :fetch )
502
- Treequel.logger.debug " ORing together %d subfilters since %p has indices" %
503
- [ expr.length, expr ]
504
- subfilters = expr.collect {|val| Treequel::Filter.new(key, val) }
505
- Treequel::Filter.new( :or, subfilters )
502
+ if expr.respond_to?( :length ) && expr.length > 1
503
+ Treequel.logger.debug " ORing together %d subfilters since %p has indices" %
504
+ [ expr.length, expr ]
505
+ subfilters = expr.collect {|val| Treequel::Filter.new(key, val) }
506
+ Treequel::Filter.new( :or, subfilters )
507
+ else
508
+ Treequel.logger.debug " unwrapping singular subfilter"
509
+ Treequel::Filter.new([ key.to_sym, expr.first ])
510
+ end
506
511
  else
507
512
  Treequel.logger.debug " value is a scalar; creating a single filter"
508
- Treequel::Filter.new([ key.to_sym, expr ])
513
+ Treequel::Filter.new( key.to_sym, expr )
509
514
  end
510
515
  end
511
516
 
@@ -655,8 +660,9 @@ class Treequel::Filter
655
660
 
656
661
  ### Create a new Treequel::Branchset::Filter with the specified +expression+.
657
662
  def initialize( *expression_parts )
663
+ self.log.debug "New filter for expression: %p" % [ expression_parts ]
658
664
  @component = self.class.parse_expression( expression_parts )
659
- self.log.debug "created a filter with component: %p" % [ @component ]
665
+ self.log.debug " expression parsed into component: %p" % [ @component ]
660
666
 
661
667
  super()
662
668
  end
@@ -212,7 +212,7 @@ class Treequel::Model < Treequel::Branch
212
212
  @dirty = false
213
213
  else
214
214
  super( directory, dn )
215
- @values = entry ? symbolify_keys( entry ) : {}
215
+ @values = symbolify_keys( entry ? entry : self.rdn_attributes )
216
216
  @dirty = true
217
217
  end
218
218
 
@@ -233,6 +233,12 @@ class Treequel::Model < Treequel::Branch
233
233
  public
234
234
  ######
235
235
 
236
+ attr_reader :values
237
+
238
+ # Unsaved attribute values hash
239
+ attr_reader :values
240
+
241
+
236
242
  ### Set up the empty hook methods
237
243
  HOOKS.each do |hook|
238
244
  define_method( hook ) do |*args|
@@ -406,42 +412,46 @@ class Treequel::Model < Treequel::Branch
406
412
  self.log.debug "Gathering modifications..."
407
413
 
408
414
  mods = []
409
- entry = self.entry || {}
410
- self.log.debug " directory entry is: %p" % [ entry ]
411
-
412
415
  @values.sort_by {|k, _| k.to_s }.each do |attribute, vals|
413
- vals = [ vals ] unless vals.is_a?( Array )
414
- vals = vals.compact
415
- vals.collect! {|val| self.get_converted_attribute(attribute, val) }
416
- self.log.debug " comparing %s values to entry: %p vs. %p" %
417
- [ attribute, vals, entry[attribute.to_s] ]
418
-
419
- entryvals = (entry[attribute.to_s] || [])
420
- attrmods = { :add => [], :delete => [] }
421
-
422
- Diff::LCS.sdiff( entryvals.sort, vals.sort ) do |change|
423
- self.log.debug " found a change: %p" % [ change ]
424
- if change.adding?
425
- attrmods[:add] << change.new_element
426
- elsif change.changed?
427
- attrmods[:add] << change.new_element
428
- attrmods[:delete] << change.old_element
429
- elsif change.deleting?
430
- attrmods[:delete] << change.old_element
431
- # else
432
- # self.log.debug " no mod necessary for %p" % [ change.action ]
433
- end
434
- end
416
+ self.log.debug " finding mods for %s" % [ attribute ]
417
+ mods += self.diff_with_entry( attribute, vals )
418
+ end
419
+
420
+ return mods
421
+ end
422
+
423
+
424
+ ### Diff the specified +values+ for the given +attribute+ against those in the directory
425
+ ### entry and return LDAP::Mod objects for any differences.
426
+ def diff_with_entry( attribute, values )
427
+ mods = []
428
+ attribute = attribute.to_s
429
+ entry = self.entry || {}
430
+ entry_values = entry.key?( attribute ) ? entry[attribute] : []
435
431
 
436
- self.log.debug " attribute %p has %d adds and %d deletes" %
437
- [ attribute, attrmods[:add].length, attrmods[:delete].length ]
438
- mods << LDAP::Mod.new( LDAP::LDAP_MOD_DELETE, attribute.to_s, attrmods[:delete] ) unless
439
- attrmods[:delete].empty?
440
- mods << LDAP::Mod.new( LDAP::LDAP_MOD_ADD, attribute.to_s, attrmods[:add] ) unless
441
- attrmods[:add].empty?
432
+ values = Array( values ).compact.
433
+ collect {|val| self.get_converted_attribute(attribute, val) }
434
+ self.log.debug " comparing %s values to entry: %p vs. %p" %
435
+ [ attribute, values, entry_values ]
436
+
437
+ Diff::LCS.sdiff( entry_values.sort, values.sort ) do |change|
438
+ if change.adding?
439
+ self.log.debug " found an addition: %p" % [ change ]
440
+ mods << LDAP::Mod.new( LDAP::LDAP_MOD_ADD, attribute, [change.new_element] )
441
+
442
+ elsif change.changed?
443
+ self.log.debug " found a modification: %p" % [ change ]
444
+ mods << LDAP::Mod.new( LDAP::LDAP_MOD_REPLACE, attribute,
445
+ [change.old_element, change.new_element] )
446
+
447
+ elsif change.deleting?
448
+ self.log.debug " found a deletion: %p" % [ change ]
449
+ mods << LDAP::Mod.new( LDAP::LDAP_MOD_DELETE, attribute, [change.old_element] )
450
+ end
442
451
  end
443
452
 
444
- self.log.debug " mods are: %p" % [ mods ]
453
+ self.log.debug " attribute %p has modifications: %p" %
454
+ [ attribute, mods ] unless mods.empty?
445
455
 
446
456
  return mods
447
457
  end
@@ -49,6 +49,7 @@ class Treequel::Model::Errors < ::Hash
49
49
 
50
50
  ### Adds an error for the given +subject+.
51
51
  def add( subject, message )
52
+ self.log.error "%s: %s" % [ subject, message ]
52
53
  self[ subject ] << message
53
54
  end
54
55
 
@@ -123,6 +123,10 @@ describe Treequel::Filter do
123
123
  should == '(|(uid=lar)(uid=bin)(uid=fon)(uid=guh))'
124
124
  end
125
125
 
126
+ it "doesn't make an OR-hash if the expression is singular" do
127
+ Treequel::Filter.new( :uid => ['lar'] ).to_s.should == '(uid=lar)'
128
+ end
129
+
126
130
  it "correctly includes OR subfilters in a Hash if the value is an Array" do
127
131
  fstr = Treequel::Filter.new( :objectClass => 'inetOrgPerson', :uid => %w[lar bin fon guh] ).to_s
128
132
 
@@ -47,9 +47,11 @@ describe Treequel::Model::SchemaValidations do
47
47
 
48
48
  it "adds an error if the object doesn't have at least one structural objectClass" do
49
49
  @conn.stub( :search_ext2 ).and_return( [] )
50
- @modelobj.object_class = ['ipHost', 'ieee802device']
51
- @modelobj.cn = 'testhost'
52
- @modelobj.ip_host_number = '127.0.0.1'
50
+ @modelobj.object_class = :posixAccount
51
+ @modelobj.cn = 'jrandom'
52
+ @modelobj.uid_number = 2881
53
+ @modelobj.gid_number = 761
54
+ @modelobj.home_directory = '/home/jrandom'
53
55
 
54
56
  @modelobj.should_not be_valid()
55
57
  @modelobj.errors.should have( 1 ).member
@@ -59,7 +61,7 @@ describe Treequel::Model::SchemaValidations do
59
61
 
60
62
  it "adds an error if the object doesn't have at least one value for all of its MUST attributes" do
61
63
  @conn.stub( :search_ext2 ).and_return( [] )
62
- @modelobj.object_class = 'person'
64
+ @modelobj.object_class = [:person, :uidObject]
63
65
 
64
66
  @modelobj.should_not be_valid()
65
67
  @modelobj.errors.should have( 2 ).members
@@ -308,6 +308,37 @@ describe Treequel::Model do
308
308
  end
309
309
 
310
310
 
311
+ describe "created via attribute transition from their parent" do
312
+
313
+ before( :each ) do
314
+ @entry = TEST_HOSTS_ENTRY.dup
315
+ @parent = Treequel::Model.new_from_entry( @entry, @directory )
316
+ end
317
+
318
+
319
+ it "has its RDN attributes set when it's a simple RDN" do
320
+ @conn.stub( :search_ext2 ).
321
+ with( "cn=wafflebreaker,#{TEST_HOSTS_DN}", LDAP::LDAP_SCOPE_BASE, "(objectClass=*)").
322
+ and_return( [] )
323
+
324
+ host = @parent.cn( :wafflebreaker )
325
+ host.object_class = :ipHost
326
+ host.cn.should == ['wafflebreaker']
327
+ end
328
+
329
+ it "has its RDN attributes set when it's a multi-value RDN" do
330
+ @conn.stub( :search_ext2 ).
331
+ with( "cn=wiffle+l=downtown,#{TEST_HOSTS_DN}", LDAP::LDAP_SCOPE_BASE, "(objectClass=*)").
332
+ and_return( [] )
333
+
334
+ host = @parent.cn( :wiffle, :l => 'downtown' )
335
+ host.object_class = :ipHost
336
+
337
+ host.cn.should == ['wiffle']
338
+ host.l.should == ['downtown']
339
+ end
340
+ end
341
+
311
342
  describe "objects loaded from entries" do
312
343
 
313
344
  before( :each ) do
@@ -501,9 +532,8 @@ describe Treequel::Model do
501
532
  result = @obj.modifications
502
533
 
503
534
  result.should be_an( Array )
504
- result.should have( 2 ).members
505
- result.should include( ldap_mod_add 'uid', 'slippy' )
506
- result.should include( ldap_mod_delete 'uid', 'slappy' )
535
+ result.should have( 1 ).members
536
+ result.should include( ldap_mod_replace 'uid', 'slappy', 'slippy' )
507
537
  end
508
538
 
509
539
  it "reverts the attribute if its #revert method is called" do
@@ -519,8 +549,7 @@ describe Treequel::Model do
519
549
 
520
550
  it "updates the modified attribute when saved" do
521
551
  @conn.should_receive( :modify ).
522
- with( TEST_PERSON_DN,
523
- [ ldap_mod_delete(:uid, 'slappy'), ldap_mod_add(:uid, 'slippy') ] )
552
+ with( TEST_PERSON_DN, [ldap_mod_replace(:uid, 'slappy', 'slippy')] )
524
553
  @obj.save
525
554
  end
526
555
 
@@ -606,15 +635,13 @@ describe Treequel::Model do
606
635
  result = @obj.modifications
607
636
 
608
637
  result.should be_an( Array )
609
- result.should have( 9 ).members
610
- result.should include( ldap_mod_delete :uid, 'slappy' )
611
- result.should include( ldap_mod_add :uid, 'fappy' )
612
- result.should include( ldap_mod_delete :givenName, 'Slappy' )
613
- result.should include( ldap_mod_add :givenName, 'Fappy' )
614
- result.should include( ldap_mod_delete :displayName, 'Slappy the Frog' )
615
- result.should include( ldap_mod_add :displayName, 'Fappy the Bear' )
616
- result.should include( ldap_mod_add :description, 'The new mascot.' )
638
+ result.should have( 6 ).members
639
+ result.should include( ldap_mod_replace :uid, 'slappy', 'fappy' )
640
+ result.should include( ldap_mod_replace :givenName, 'Slappy', 'Fappy' )
641
+ result.should include( ldap_mod_replace :displayName, 'Slappy the Frog',
642
+ 'Fappy the Bear' )
617
643
  result.should include( ldap_mod_delete :description, 'Alright.' )
644
+ result.should include( ldap_mod_add :description, 'The new mascot.' )
618
645
  result.should include( ldap_mod_delete :l, 'a forest in England' )
619
646
 
620
647
  end
@@ -674,7 +701,9 @@ describe Treequel::Model do
674
701
  ldap_mod_add("gidNumber", "200"),
675
702
  ldap_mod_add("homeDirectory", "/u/j/jrandom"),
676
703
  ldap_mod_add("l", "a forest in England"),
677
- ldap_mod_add("objectClass", "inetOrgPerson", "person", "posixAccount"),
704
+ ldap_mod_add("objectClass", "inetOrgPerson"),
705
+ ldap_mod_add("objectClass", "person"),
706
+ ldap_mod_add("objectClass", "posixAccount"),
678
707
  ldap_mod_add("sn", "Hacker"),
679
708
  ldap_mod_add("uid", "jrandom"),
680
709
  ldap_mod_add("uidNumber", "1121")
metadata CHANGED
@@ -1,205 +1,231 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: treequel
3
- version: !ruby/object:Gem::Version
4
- version: 1.7.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
5
  prerelease:
6
+ segments:
7
+ - 1
8
+ - 7
9
+ - 1
10
+ version: 1.7.1
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Michael Granger
9
14
  - Mahlon E. Smith
10
15
  autorequire:
11
16
  bindir: bin
12
- cert_chain:
13
- - ! '-----BEGIN CERTIFICATE-----
14
-
17
+ cert_chain:
18
+ - |
19
+ -----BEGIN CERTIFICATE-----
15
20
  MIIDLDCCAhSgAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQwwCgYDVQQDDANnZWQx
16
-
17
21
  FzAVBgoJkiaJk/IsZAEZFgdfYWVyaWVfMRMwEQYKCZImiZPyLGQBGRYDb3JnMB4X
18
-
19
22
  DTEwMDkxNjE0NDg1MVoXDTExMDkxNjE0NDg1MVowPDEMMAoGA1UEAwwDZ2VkMRcw
20
-
21
23
  FQYKCZImiZPyLGQBGRYHX2FlcmllXzETMBEGCgmSJomT8ixkARkWA29yZzCCASIw
22
-
23
24
  DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy//BFxC1f/cPSnwtJBWoFiFrir
24
-
25
25
  h7RicI+joq/ocVXQqI4TDWPyF/8tqkvt+rD99X9qs2YeR8CU/YiIpLWrQOYST70J
26
-
27
26
  vDn7Uvhb2muFVqq6+vobeTkILBEO6pionWDG8jSbo3qKm1RjKJDwg9p4wNKhPuu8
28
-
29
27
  KGue/BFb67KflqyApPmPeb3Vdd9clspzqeFqp7cUBMEpFS6LWxy4Gk+qvFFJBJLB
30
-
31
28
  BUHE/LZVJMVzfpC5Uq+QmY7B+FH/QqNndn3tOHgsPadLTNimuB1sCuL1a4z3Pepd
32
-
33
29
  TeLBEFmEao5Dk3K/Q8o8vlbIB/jBDTUx6Djbgxw77909x6gI9doU4LD5XMcCAwEA
34
-
35
30
  AaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJeoGkOr9l4B
36
-
37
31
  +saMkW/ZXT4UeSvVMA0GCSqGSIb3DQEBBQUAA4IBAQBG2KObvYI2eHyyBUJSJ3jN
38
-
39
32
  vEnU3d60znAXbrSd2qb3r1lY1EPDD3bcy0MggCfGdg3Xu54z21oqyIdk8uGtWBPL
40
-
41
33
  HIa9EgfFGSUEgvcIvaYqiN4jTUtidfEFw+Ltjs8AP9gWgSIYS6Gr38V0WGFFNzIH
42
-
43
34
  aOD2wmu9oo/RffW4hS/8GuvfMzcw7CQ355wFR4KB/nyze+EsZ1Y5DerCAagMVuDQ
44
-
45
35
  U0BLmWDFzPGGWlPeQCrYHCr+AcJz+NRnaHCKLZdSKj/RHuTOt+gblRex8FAh8NeA
46
-
47
36
  cmlhXe46pZNJgWKbxZah85jIjx95hR8vOI+NAM5iH9kOqK13DrxacTKPhqj5PjwF
48
-
49
37
  -----END CERTIFICATE-----
50
38
 
51
- '
52
- date: 2011-11-10 00:00:00.000000000 Z
53
- dependencies:
54
- - !ruby/object:Gem::Dependency
39
+ date: 2011-11-28 00:00:00 Z
40
+ dependencies:
41
+ - !ruby/object:Gem::Dependency
55
42
  name: ruby-ldap
56
- requirement: &70222008767240 !ruby/object:Gem::Requirement
43
+ prerelease: false
44
+ requirement: &id001 !ruby/object:Gem::Requirement
57
45
  none: false
58
- requirements:
46
+ requirements:
59
47
  - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '0.9'
48
+ - !ruby/object:Gem::Version
49
+ hash: 25
50
+ segments:
51
+ - 0
52
+ - 9
53
+ version: "0.9"
62
54
  type: :runtime
63
- prerelease: false
64
- version_requirements: *70222008767240
65
- - !ruby/object:Gem::Dependency
55
+ version_requirements: *id001
56
+ - !ruby/object:Gem::Dependency
66
57
  name: diff-lcs
67
- requirement: &70222008766820 !ruby/object:Gem::Requirement
58
+ prerelease: false
59
+ requirement: &id002 !ruby/object:Gem::Requirement
68
60
  none: false
69
- requirements:
61
+ requirements:
70
62
  - - ~>
71
- - !ruby/object:Gem::Version
72
- version: '1.1'
63
+ - !ruby/object:Gem::Version
64
+ hash: 13
65
+ segments:
66
+ - 1
67
+ - 1
68
+ version: "1.1"
73
69
  type: :runtime
74
- prerelease: false
75
- version_requirements: *70222008766820
76
- - !ruby/object:Gem::Dependency
70
+ version_requirements: *id002
71
+ - !ruby/object:Gem::Dependency
77
72
  name: hoe-mercurial
78
- requirement: &70222008766400 !ruby/object:Gem::Requirement
79
- none: false
80
- requirements:
81
- - - ~>
82
- - !ruby/object:Gem::Version
83
- version: 1.3.1
84
- type: :development
85
73
  prerelease: false
86
- version_requirements: *70222008766400
87
- - !ruby/object:Gem::Dependency
88
- name: hoe-manualgen
89
- requirement: &70222008782300 !ruby/object:Gem::Requirement
74
+ requirement: &id003 !ruby/object:Gem::Requirement
90
75
  none: false
91
- requirements:
76
+ requirements:
92
77
  - - ~>
93
- - !ruby/object:Gem::Version
94
- version: 0.2.0
78
+ - !ruby/object:Gem::Version
79
+ hash: 25
80
+ segments:
81
+ - 1
82
+ - 3
83
+ - 1
84
+ version: 1.3.1
95
85
  type: :development
96
- prerelease: false
97
- version_requirements: *70222008782300
98
- - !ruby/object:Gem::Dependency
86
+ version_requirements: *id003
87
+ - !ruby/object:Gem::Dependency
99
88
  name: hoe-highline
100
- requirement: &70222008781880 !ruby/object:Gem::Requirement
89
+ prerelease: false
90
+ requirement: &id004 !ruby/object:Gem::Requirement
101
91
  none: false
102
- requirements:
92
+ requirements:
103
93
  - - ~>
104
- - !ruby/object:Gem::Version
94
+ - !ruby/object:Gem::Version
95
+ hash: 29
96
+ segments:
97
+ - 0
98
+ - 0
99
+ - 1
105
100
  version: 0.0.1
106
101
  type: :development
107
- prerelease: false
108
- version_requirements: *70222008781880
109
- - !ruby/object:Gem::Dependency
102
+ version_requirements: *id004
103
+ - !ruby/object:Gem::Dependency
110
104
  name: rspec
111
- requirement: &70222008781420 !ruby/object:Gem::Requirement
105
+ prerelease: false
106
+ requirement: &id005 !ruby/object:Gem::Requirement
112
107
  none: false
113
- requirements:
108
+ requirements:
114
109
  - - ~>
115
- - !ruby/object:Gem::Version
116
- version: '2.7'
110
+ - !ruby/object:Gem::Version
111
+ hash: 13
112
+ segments:
113
+ - 2
114
+ - 7
115
+ version: "2.7"
117
116
  type: :development
118
- prerelease: false
119
- version_requirements: *70222008781420
120
- - !ruby/object:Gem::Dependency
117
+ version_requirements: *id005
118
+ - !ruby/object:Gem::Dependency
121
119
  name: ruby-termios
122
- requirement: &70222008781000 !ruby/object:Gem::Requirement
120
+ prerelease: false
121
+ requirement: &id006 !ruby/object:Gem::Requirement
123
122
  none: false
124
- requirements:
123
+ requirements:
125
124
  - - ~>
126
- - !ruby/object:Gem::Version
127
- version: '0.9'
125
+ - !ruby/object:Gem::Version
126
+ hash: 25
127
+ segments:
128
+ - 0
129
+ - 9
130
+ version: "0.9"
128
131
  type: :development
129
- prerelease: false
130
- version_requirements: *70222008781000
131
- - !ruby/object:Gem::Dependency
132
+ version_requirements: *id006
133
+ - !ruby/object:Gem::Dependency
132
134
  name: ruby-terminfo
133
- requirement: &70222008780580 !ruby/object:Gem::Requirement
135
+ prerelease: false
136
+ requirement: &id007 !ruby/object:Gem::Requirement
134
137
  none: false
135
- requirements:
138
+ requirements:
136
139
  - - ~>
137
- - !ruby/object:Gem::Version
138
- version: '0.1'
140
+ - !ruby/object:Gem::Version
141
+ hash: 9
142
+ segments:
143
+ - 0
144
+ - 1
145
+ version: "0.1"
139
146
  type: :development
140
- prerelease: false
141
- version_requirements: *70222008780580
142
- - !ruby/object:Gem::Dependency
147
+ version_requirements: *id007
148
+ - !ruby/object:Gem::Dependency
143
149
  name: columnize
144
- requirement: &70222008780160 !ruby/object:Gem::Requirement
150
+ prerelease: false
151
+ requirement: &id008 !ruby/object:Gem::Requirement
145
152
  none: false
146
- requirements:
153
+ requirements:
147
154
  - - ~>
148
- - !ruby/object:Gem::Version
149
- version: '0.3'
155
+ - !ruby/object:Gem::Version
156
+ hash: 13
157
+ segments:
158
+ - 0
159
+ - 3
160
+ version: "0.3"
150
161
  type: :development
151
- prerelease: false
152
- version_requirements: *70222008780160
153
- - !ruby/object:Gem::Dependency
162
+ version_requirements: *id008
163
+ - !ruby/object:Gem::Dependency
154
164
  name: sysexits
155
- requirement: &70222008779740 !ruby/object:Gem::Requirement
165
+ prerelease: false
166
+ requirement: &id009 !ruby/object:Gem::Requirement
156
167
  none: false
157
- requirements:
168
+ requirements:
158
169
  - - ~>
159
- - !ruby/object:Gem::Version
160
- version: '1.0'
170
+ - !ruby/object:Gem::Version
171
+ hash: 15
172
+ segments:
173
+ - 1
174
+ - 0
175
+ version: "1.0"
161
176
  type: :development
162
- prerelease: false
163
- version_requirements: *70222008779740
164
- - !ruby/object:Gem::Dependency
177
+ version_requirements: *id009
178
+ - !ruby/object:Gem::Dependency
165
179
  name: sequel
166
- requirement: &70222008779320 !ruby/object:Gem::Requirement
180
+ prerelease: false
181
+ requirement: &id010 !ruby/object:Gem::Requirement
167
182
  none: false
168
- requirements:
183
+ requirements:
169
184
  - - ~>
170
- - !ruby/object:Gem::Version
171
- version: '3.20'
185
+ - !ruby/object:Gem::Version
186
+ hash: 47
187
+ segments:
188
+ - 3
189
+ - 20
190
+ version: "3.20"
172
191
  type: :development
173
- prerelease: false
174
- version_requirements: *70222008779320
175
- - !ruby/object:Gem::Dependency
192
+ version_requirements: *id010
193
+ - !ruby/object:Gem::Dependency
176
194
  name: hoe
177
- requirement: &70222008778900 !ruby/object:Gem::Requirement
195
+ prerelease: false
196
+ requirement: &id011 !ruby/object:Gem::Requirement
178
197
  none: false
179
- requirements:
198
+ requirements:
180
199
  - - ~>
181
- - !ruby/object:Gem::Version
182
- version: '2.12'
200
+ - !ruby/object:Gem::Version
201
+ hash: 27
202
+ segments:
203
+ - 2
204
+ - 12
205
+ version: "2.12"
183
206
  type: :development
184
- prerelease: false
185
- version_requirements: *70222008778900
186
- description: ! "Treequel is an LDAP toolkit for Ruby. It is intended to allow quick,
187
- easy\naccess to LDAP directories in a manner consistent with LDAP's hierarchical,\nfree-form
188
- nature. \n\nIt's inspired by and modeled after [Sequel](http://sequel.rubyforge.org/),
189
- a\nkick-ass database library."
190
- email:
207
+ version_requirements: *id011
208
+ description: |-
209
+ Treequel is an LDAP toolkit for Ruby. It is intended to allow quick, easy
210
+ access to LDAP directories in a manner consistent with LDAP's hierarchical,
211
+ free-form nature.
212
+
213
+ It's inspired by and modeled after [Sequel](http://sequel.rubyforge.org/), a
214
+ kick-ass database library.
215
+ email:
191
216
  - ged@FaerieMUD.org
192
217
  - mahlon@martini.nu
193
- executables:
218
+ executables:
194
219
  - treeirb
195
220
  - treequel
196
221
  - treewhat
197
222
  extensions: []
198
- extra_rdoc_files:
223
+
224
+ extra_rdoc_files:
199
225
  - Manifest.txt
200
226
  - History.rdoc
201
227
  - README.rdoc
202
- files:
228
+ files:
203
229
  - .gemtest
204
230
  - ChangeLog
205
231
  - History.rdoc
@@ -273,33 +299,50 @@ files:
273
299
  - spec/treequel/schema_spec.rb
274
300
  - spec/treequel_spec.rb
275
301
  homepage: http://deveiate.org/projects/Treequel
276
- licenses:
302
+ licenses:
277
303
  - BSD
278
- post_install_message: ! "If you want to use the included 'treequel' LDAP shell, you'll
279
- need to install\nthe following libraries as well:\n\n - ruby-termios\n - ruby-terminfo\n
280
- \ - columnize\n - sysexits\n\nYou can install them automatically if you use
281
- the --development flag when\ninstalling Treequel."
282
- rdoc_options:
304
+ post_install_message: |-
305
+ If you want to use the included 'treequel' LDAP shell, you'll need to install
306
+ the following libraries as well:
307
+
308
+ - ruby-termios
309
+ - ruby-terminfo
310
+ - columnize
311
+ - sysexits
312
+
313
+ You can install them automatically if you use the --development flag when
314
+ installing Treequel.
315
+ rdoc_options:
283
316
  - --main
284
317
  - README.rdoc
285
- require_paths:
318
+ require_paths:
286
319
  - lib
287
- required_ruby_version: !ruby/object:Gem::Requirement
320
+ required_ruby_version: !ruby/object:Gem::Requirement
288
321
  none: false
289
- requirements:
290
- - - ! '>='
291
- - !ruby/object:Gem::Version
322
+ requirements:
323
+ - - ">="
324
+ - !ruby/object:Gem::Version
325
+ hash: 57
326
+ segments:
327
+ - 1
328
+ - 8
329
+ - 7
292
330
  version: 1.8.7
293
- required_rubygems_version: !ruby/object:Gem::Requirement
331
+ required_rubygems_version: !ruby/object:Gem::Requirement
294
332
  none: false
295
- requirements:
296
- - - ! '>='
297
- - !ruby/object:Gem::Version
298
- version: '0'
333
+ requirements:
334
+ - - ">="
335
+ - !ruby/object:Gem::Version
336
+ hash: 3
337
+ segments:
338
+ - 0
339
+ version: "0"
299
340
  requirements: []
341
+
300
342
  rubyforge_project: treequel
301
343
  rubygems_version: 1.8.11
302
344
  signing_key:
303
345
  specification_version: 3
304
346
  summary: Treequel is an LDAP toolkit for Ruby
305
347
  test_files: []
348
+
metadata.gz.sig CHANGED
Binary file