treequel 1.0.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.
Files changed (74) hide show
  1. data/ChangeLog +354 -0
  2. data/LICENSE +27 -0
  3. data/README +66 -0
  4. data/Rakefile +345 -0
  5. data/Rakefile.local +43 -0
  6. data/bin/treeirb +14 -0
  7. data/bin/treequel +229 -0
  8. data/examples/company-directory.rb +112 -0
  9. data/examples/ldap-monitor.rb +143 -0
  10. data/examples/ldap-monitor/public/css/master.css +328 -0
  11. data/examples/ldap-monitor/public/images/card_small.png +0 -0
  12. data/examples/ldap-monitor/public/images/chain_small.png +0 -0
  13. data/examples/ldap-monitor/public/images/globe_small.png +0 -0
  14. data/examples/ldap-monitor/public/images/globe_small_green.png +0 -0
  15. data/examples/ldap-monitor/public/images/plug.png +0 -0
  16. data/examples/ldap-monitor/public/images/shadows/large-30-down.png +0 -0
  17. data/examples/ldap-monitor/public/images/tick.png +0 -0
  18. data/examples/ldap-monitor/public/images/tick_circle.png +0 -0
  19. data/examples/ldap-monitor/public/images/treequel-favicon.png +0 -0
  20. data/examples/ldap-monitor/views/backends.erb +41 -0
  21. data/examples/ldap-monitor/views/connections.erb +74 -0
  22. data/examples/ldap-monitor/views/databases.erb +39 -0
  23. data/examples/ldap-monitor/views/dump_subsystem.erb +14 -0
  24. data/examples/ldap-monitor/views/index.erb +14 -0
  25. data/examples/ldap-monitor/views/layout.erb +35 -0
  26. data/examples/ldap-monitor/views/listeners.erb +30 -0
  27. data/examples/ldap_state.rb +62 -0
  28. data/lib/treequel.rb +145 -0
  29. data/lib/treequel/branch.rb +589 -0
  30. data/lib/treequel/branchcollection.rb +204 -0
  31. data/lib/treequel/branchset.rb +360 -0
  32. data/lib/treequel/constants.rb +604 -0
  33. data/lib/treequel/directory.rb +541 -0
  34. data/lib/treequel/exceptions.rb +32 -0
  35. data/lib/treequel/filter.rb +704 -0
  36. data/lib/treequel/mixins.rb +325 -0
  37. data/lib/treequel/schema.rb +245 -0
  38. data/lib/treequel/schema/attributetype.rb +252 -0
  39. data/lib/treequel/schema/ldapsyntax.rb +96 -0
  40. data/lib/treequel/schema/matchingrule.rb +124 -0
  41. data/lib/treequel/schema/matchingruleuse.rb +124 -0
  42. data/lib/treequel/schema/objectclass.rb +289 -0
  43. data/lib/treequel/sequel_integration.rb +26 -0
  44. data/lib/treequel/utils.rb +169 -0
  45. data/rake/191_compat.rb +26 -0
  46. data/rake/dependencies.rb +76 -0
  47. data/rake/helpers.rb +434 -0
  48. data/rake/hg.rb +261 -0
  49. data/rake/manual.rb +782 -0
  50. data/rake/packaging.rb +135 -0
  51. data/rake/publishing.rb +318 -0
  52. data/rake/rdoc.rb +30 -0
  53. data/rake/style.rb +62 -0
  54. data/rake/svn.rb +668 -0
  55. data/rake/testing.rb +187 -0
  56. data/rake/verifytask.rb +64 -0
  57. data/rake/win32.rb +190 -0
  58. data/spec/lib/constants.rb +93 -0
  59. data/spec/lib/helpers.rb +100 -0
  60. data/spec/treequel/branch_spec.rb +569 -0
  61. data/spec/treequel/branchcollection_spec.rb +213 -0
  62. data/spec/treequel/branchset_spec.rb +376 -0
  63. data/spec/treequel/directory_spec.rb +487 -0
  64. data/spec/treequel/filter_spec.rb +482 -0
  65. data/spec/treequel/mixins_spec.rb +330 -0
  66. data/spec/treequel/schema/attributetype_spec.rb +237 -0
  67. data/spec/treequel/schema/ldapsyntax_spec.rb +83 -0
  68. data/spec/treequel/schema/matchingrule_spec.rb +158 -0
  69. data/spec/treequel/schema/matchingruleuse_spec.rb +137 -0
  70. data/spec/treequel/schema/objectclass_spec.rb +262 -0
  71. data/spec/treequel/schema_spec.rb +118 -0
  72. data/spec/treequel/utils_spec.rb +49 -0
  73. data/spec/treequel_spec.rb +179 -0
  74. metadata +169 -0
@@ -0,0 +1,135 @@
1
+ #
2
+ # Packaging Rake Tasks
3
+
4
+ #
5
+
6
+ require 'rbconfig'
7
+ require 'pathname'
8
+ require 'rake/packagetask'
9
+ require 'rake/gempackagetask'
10
+
11
+ require Pathname( __FILE__ ).dirname.expand_path + 'hg.rb'
12
+
13
+ include Config
14
+
15
+ ### Task: gem
16
+ ### Task: package
17
+ Rake::PackageTask.new( PKG_NAME, PKG_VERSION ) do |task|
18
+ task.need_tar_gz = true
19
+ task.need_tar_bz2 = true
20
+ task.need_zip = true
21
+ task.package_dir = PKGDIR.to_s
22
+ task.package_files = RELEASE_FILES.collect {|f| f.to_s }
23
+ end
24
+ task :package => [:gem]
25
+
26
+
27
+ ### Task: gem
28
+ gempath = PKGDIR + GEM_FILE_NAME
29
+
30
+ desc "Build a RubyGem package (#{GEM_FILE_NAME})"
31
+ task :gem => gempath.to_s
32
+ file gempath.to_s => [PKGDIR.to_s] + GEMSPEC.files do
33
+ when_writing( "Creating GEM" ) do
34
+ Gem::Builder.new( GEMSPEC ).build
35
+ verbose( true ) do
36
+ mv GEM_FILE_NAME, gempath
37
+ end
38
+ end
39
+ end
40
+
41
+
42
+ prerelease_gempath = PKGDIR + SNAPSHOT_GEM_NAME
43
+
44
+ desc "Build a pre-release RubyGem package"
45
+ task :prerelease_gem => prerelease_gempath.to_s
46
+ file prerelease_gempath.to_s => [PKGDIR.to_s] + GEMSPEC.files do
47
+ when_writing( "Creating prerelease GEM" ) do
48
+ gemspec = GEMSPEC.clone
49
+ gemspec.version = Gem::Version.create( "%s.%s" % [GEMSPEC.version, PKG_BUILD] )
50
+ Gem::Builder.new( gemspec ).build
51
+ verbose( true ) do
52
+ mv SNAPSHOT_GEM_NAME, prerelease_gempath
53
+ end
54
+ end
55
+ end
56
+
57
+
58
+ ### Task: install
59
+ desc "Install #{PKG_NAME} as a conventional library"
60
+ task :install => "spec:quiet" do
61
+ log "Installing #{PKG_NAME} as a conventional library"
62
+ sitelib = Pathname.new( CONFIG['sitelibdir'] )
63
+ sitearch = Pathname.new( CONFIG['sitearchdir'] )
64
+ Dir.chdir( LIBDIR ) do
65
+ LIB_FILES.collect {|path| Pathname(path) }.each do |libfile|
66
+ relpath = libfile.relative_path_from( LIBDIR )
67
+ target = sitelib + relpath
68
+ FileUtils.mkpath target.dirname,
69
+ :mode => 0755, :verbose => true, :noop => $dryrun unless target.dirname.directory?
70
+ FileUtils.install relpath, target,
71
+ :mode => 0644, :verbose => true, :noop => $dryrun
72
+ end
73
+ end
74
+ if EXTDIR.exist?
75
+ trace " looking for a binary extension (%s)" % [ EXTDIR + "*.#{Config::CONFIG['DLEXT']}" ]
76
+ Dir.chdir( EXTDIR ) do
77
+ Pathname.glob( "*.#{Config::CONFIG['DLEXT']}" ) do |dl|
78
+ trace " found: #{dl}"
79
+ target = sitearch + dl.basename
80
+ FileUtils.install dl, target,
81
+ :mode => 0755, :verbose => true, :noop => $dryrun
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+
88
+
89
+ ### Task: install_gem
90
+ desc "Install #{PKG_NAME} from a locally-built gem"
91
+ task :install_gem => [:package] do
92
+ $stderr.puts
93
+ installer = Gem::Installer.new( %{pkg/#{PKG_FILE_NAME}.gem} )
94
+ installer.install
95
+ end
96
+
97
+
98
+ ### Task: uninstall
99
+ desc "Uninstall #{PKG_NAME} if it's been installed as a conventional library"
100
+ task :uninstall do
101
+ log "Uninstalling conventionally-installed #{PKG_NAME} library files"
102
+ sitelib = Pathname.new( CONFIG['sitelibdir'] )
103
+ sitearch = Pathname.new( CONFIG['sitearchdir'] )
104
+
105
+ Dir.chdir( LIBDIR ) do
106
+ LIB_FILES.collect {|path| Pathname(path) }.each do |libfile|
107
+ relpath = libfile.relative_path_from( LIBDIR )
108
+ target = sitelib + relpath
109
+ FileUtils.rm_f target, :verbose => true, :noop => $dryrun
110
+ FileUtils.rm_rf( target.dirname, :verbose => true, :noop => $dryrun ) if
111
+ target.dirname.entries.empty?
112
+ end
113
+ end
114
+ if EXTDIR.exist?
115
+ trace " looking for a binary extension (%s)" % [ EXTDIR + "*.#{Config::CONFIG['DLEXT']}" ]
116
+ Dir.chdir( EXTDIR ) do
117
+ Pathname.glob( "*.#{Config::CONFIG['DLEXT']}" ) do |dl|
118
+ trace " found: #{dl}"
119
+ target = sitearch + dl.basename
120
+ FileUtils.rm target, :verbose => true, :noop => $dryrun
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+ ### Task: uninstall_gem
128
+ desc "Install the #{PKG_NAME} gem"
129
+ task :uninstall_gem => [:clean] do
130
+ uninstaller = Gem::Uninstaller.new( PKG_FILE_NAME )
131
+ uninstaller.uninstall
132
+ end
133
+
134
+
135
+
@@ -0,0 +1,318 @@
1
+ #####################################################################
2
+ ### P U B L I C A T I O N T A S K S
3
+ #####################################################################
4
+
5
+ RELEASE_NOTES_FILE = 'release.notes'
6
+ RELEASE_ANNOUNCE_FILE = 'release.ann'
7
+
8
+ require 'net/smtp'
9
+ require 'net/protocol'
10
+ require 'openssl'
11
+
12
+ $publish_privately = false
13
+
14
+ ### Add SSL to Net::SMTP
15
+ class Net::SMTP
16
+ def ssl_start( helo='localhost.localdomain', user=nil, secret=nil, authtype=nil )
17
+ if block_given?
18
+ begin
19
+ do_ssl_start( helo, user, secret, authtype )
20
+ return yield( self )
21
+ ensure
22
+ do_finish
23
+ end
24
+ else
25
+ do_ssl_start( helo, user, secret, authtype )
26
+ return self
27
+ end
28
+ end
29
+
30
+
31
+ #######
32
+ private
33
+ #######
34
+
35
+ def do_ssl_start( helodomain, user, secret, authtype )
36
+ raise IOError, 'SMTP session already started' if @started
37
+ check_auth_args user, secret, authtype if user or secret
38
+
39
+ # Open the connection
40
+ @debug_output << "opening connection to #{@address}...\n" if @debug_output
41
+ sock = timeout( @open_timeout ) { TCPsocket.new(@address, @port) }
42
+
43
+ # Wrap it in the SSL layer
44
+ ssl_context = OpenSSL::SSL::SSLContext.new
45
+ ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
46
+ ssl_sock = OpenSSL::SSL::SSLSocket.new( sock, ssl_context )
47
+ ssl_sock.sync_close = true
48
+ ssl_sock.connect
49
+
50
+ # Wrap it in the message-oriented IO layer
51
+ sslmsgio = Net::InternetMessageIO.new( ssl_sock )
52
+ sslmsgio.read_timeout = @read_timeout
53
+ sslmsgio.debug_output = @debug_output
54
+
55
+ @socket = sslmsgio
56
+
57
+ check_response(critical { recv_response() })
58
+ begin
59
+ if @esmtp
60
+ ehlo helodomain
61
+ else
62
+ helo helodomain
63
+ end
64
+ rescue ProtocolError
65
+ if @esmtp
66
+ @esmtp = false
67
+ @error_occured = false
68
+ retry
69
+ end
70
+ raise
71
+ end
72
+ authenticate user, secret, authtype if user
73
+ @started = true
74
+ ensure
75
+ @socket.close if not @started and @socket and not @socket.closed?
76
+ end
77
+ end
78
+
79
+
80
+ begin
81
+ gem 'text-format'
82
+
83
+ require 'time'
84
+ require 'rake/tasklib'
85
+ require 'tmail'
86
+ require 'net/smtp'
87
+ require 'etc'
88
+ require 'rubyforge'
89
+ require 'socket'
90
+ require 'text/format'
91
+
92
+ ### Generate a valid RFC822 message-id
93
+ def gen_message_id
94
+ return "<%s.%s@%s>" % [
95
+ (Time.now.to_f * 10000).to_i.to_s( 36 ),
96
+ (rand( 2 ** 64 - 1 )).to_s( 36 ),
97
+ Socket.gethostname
98
+ ]
99
+ end
100
+
101
+
102
+ namespace :release do
103
+ task :default => [ :prep_release, :upload, :publish, :announce ]
104
+
105
+ desc "Re-publish the release with the current version number"
106
+ task :rerelease => [ :upload, :publish, :announce ]
107
+
108
+ desc "Re-run the publication tasks, but send notifications to debugging address"
109
+ task :test do
110
+ trace "Will publish privately"
111
+ $publish_privately = true
112
+ Rake::Task['release:rerelease'].invoke
113
+ end
114
+
115
+
116
+ desc "Generate the release notes"
117
+ task :notes => [RELEASE_NOTES_FILE]
118
+ file RELEASE_NOTES_FILE do |task|
119
+ last_tag = MercurialHelpers.get_tags.grep( /\d+\.\d+\.\d+/ ).
120
+ collect {|ver| vvec(ver) }.sort.last.unpack( 'N*' ).join('.')
121
+
122
+ File.open( task.name, File::WRONLY|File::TRUNC|File::CREAT ) do |fh|
123
+ fh.puts "Release Notes for #{PKG_VERSION}",
124
+ "--------------------------------", '', ''
125
+ end
126
+
127
+ edit task.name
128
+ end
129
+ CLOBBER.include( RELEASE_NOTES_FILE )
130
+
131
+
132
+ desc "Upload project documentation and packages to #{PROJECT_HOST}"
133
+ task :upload => [ :upload_docs, :upload_packages ]
134
+ task :project => :upload # the old name
135
+
136
+ desc "Publish the project docs to #{PROJECT_HOST}"
137
+ task :upload_docs => [ :rdoc ] do
138
+ when_writing( "Publishing docs to #{PROJECT_SCPDOCURL}" ) do
139
+ log "Uploading API documentation to %s:%s" % [ PROJECT_HOST, PROJECT_DOCDIR ]
140
+ run 'ssh', PROJECT_HOST, "rm -rf #{PROJECT_DOCDIR}"
141
+ run 'scp', '-qCr', RDOCDIR, PROJECT_SCPDOCURL
142
+ end
143
+ end
144
+
145
+ desc "Publish the project packages to #{PROJECT_HOST}"
146
+ task :upload_packages => [ :package ] do
147
+ when_writing( "Uploading packages") do
148
+ pkgs = Pathname.glob( PKGDIR + "#{PKG_FILE_NAME}.{gem,tar.gz,tar.bz2,zip}" )
149
+ log "Uploading %d packages to #{PROJECT_SCPPUBURL}" % [ pkgs.length ]
150
+ pkgs.each do |pkgfile|
151
+ run 'scp', '-qC', pkgfile, PROJECT_SCPPUBURL
152
+ end
153
+ end
154
+ end
155
+
156
+
157
+ file RELEASE_ANNOUNCE_FILE => [RELEASE_NOTES_FILE] do |task|
158
+ relnotes = File.read( RELEASE_NOTES_FILE )
159
+ announce_body = %{
160
+
161
+ Version #{PKG_VERSION} of #{PKG_NAME} has been released.
162
+
163
+ #{Text::Format.new(:first_indent => 0).format_one_paragraph(GEMSPEC.description)}
164
+
165
+ == Project Page
166
+
167
+ #{GEMSPEC.homepage}
168
+
169
+ == Installation
170
+
171
+ Via gems:
172
+
173
+ $ sudo gem install #{GEMSPEC.name}
174
+
175
+ or from source:
176
+
177
+ $ wget http://deveiate.org/code/#{PKG_FILE_NAME}.tar.gz
178
+ $ tar -xzvf #{PKG_FILE_NAME}.tar.gz
179
+ $ cd #{PKG_FILE_NAME}
180
+ $ sudo rake install
181
+
182
+ == Changes
183
+ #{relnotes}
184
+ }.gsub( /^\t+/, '' )
185
+
186
+ File.open( task.name, File::WRONLY|File::TRUNC|File::CREAT ) do |fh|
187
+ fh.print( announce_body )
188
+ end
189
+
190
+ edit task.name
191
+ end
192
+ CLOBBER.include( RELEASE_ANNOUNCE_FILE )
193
+
194
+
195
+ desc 'Send out a release announcement'
196
+ task :announce => [RELEASE_ANNOUNCE_FILE] do
197
+ email = TMail::Mail.new
198
+ if $publish_privately
199
+ trace "Sending private announce mail"
200
+ email.to = 'rubymage@gmail.com'
201
+ else
202
+ trace "Sending public announce mail"
203
+ email.to = 'Ruby-Talk List <ruby-talk@ruby-lang.org>'
204
+ email.bcc = 'rubymage@gmail.com'
205
+ end
206
+ email.from = GEMSPEC.email
207
+ email.subject = "[ANN] #{PKG_NAME} #{PKG_VERSION}"
208
+ email.body = File.read( RELEASE_ANNOUNCE_FILE )
209
+ email.date = Time.new
210
+
211
+ email.message_id = gen_message_id()
212
+
213
+ log "About to send the following email:"
214
+ puts '---',
215
+ email.to_s,
216
+ '---'
217
+
218
+ ask_for_confirmation( "Will send via #{SMTP_HOST}." ) do
219
+ pwent = Etc.getpwuid( Process.euid )
220
+ curuser = pwent ? pwent.name : 'unknown'
221
+ username = prompt_with_default( "SMTP user", curuser )
222
+ password = prompt_for_password()
223
+
224
+ trace "Creating SMTP connection to #{SMTP_HOST}:#{SMTP_PORT}"
225
+ smtp = Net::SMTP.new( SMTP_HOST, SMTP_PORT )
226
+ smtp.set_debug_output( $stdout )
227
+ smtp.esmtp = true
228
+
229
+ trace "connecting..."
230
+ smtp.ssl_start( Socket.gethostname, username, password, :plain ) do |smtp|
231
+ trace "sending message..."
232
+ smtp.send_message( email.to_s, email.from, email.to )
233
+ end
234
+ trace "done."
235
+ end
236
+ end
237
+
238
+
239
+ desc 'Publish the new release to RubyForge'
240
+ task :publish => [:clean, :package, :notes] do |task|
241
+ project = GEMSPEC.rubyforge_project
242
+
243
+ if $publish_privately
244
+ log "Skipping push of release files to RubyForge"
245
+ else
246
+ rf = RubyForge.new
247
+ log "Loading RubyForge config"
248
+ rf.configure
249
+
250
+ group_id = rf.autoconfig['group_ids'][RUBYFORGE_GROUP] or
251
+ fail "Your configuration doesn't have a group id for '#{RUBYFORGE_GROUP}'"
252
+
253
+ # If this project doesn't yet exist, create it
254
+ unless rf.autoconfig['package_ids'].key?( project )
255
+ ask_for_confirmation( "Package '#{project}' doesn't exist on RubyForge. Create it?" ) do
256
+ log "Creating new package '#{project}'"
257
+ rf.create_package( group_id, project )
258
+ end
259
+ end
260
+
261
+ package_id = rf.autoconfig['package_ids'][ project ]
262
+
263
+ # Make sure this release doesn't already exist
264
+ releases = rf.autoconfig['release_ids']
265
+ if releases.key?( GEMSPEC.name ) && releases[ GEMSPEC.name ].key?( PKG_VERSION )
266
+ log "Rubyforge seems to already have #{ PKG_FILE_NAME }"
267
+ else
268
+ config = rf.userconfig or
269
+ fail "You apparently haven't set up your RubyForge credentials on this machine."
270
+ config['release_notes'] = GEMSPEC.description
271
+ config['release_changes'] = File.read( RELEASE_NOTES_FILE )
272
+
273
+ files = FileList[ PKGDIR + GEM_FILE_NAME ]
274
+ files.include PKGDIR + "#{PKG_FILE_NAME}.tar.gz"
275
+ files.include PKGDIR + "#{PKG_FILE_NAME}.tar.bz2"
276
+ files.include PKGDIR + "#{PKG_FILE_NAME}.zip"
277
+
278
+ log "Releasing #{PKG_FILE_NAME}"
279
+ when_writing do
280
+ log "Publishing to RubyForge: \n",
281
+ "\tproject: #{RUBYFORGE_GROUP}\n",
282
+ "\tpackage: #{PKG_NAME.downcase}\n",
283
+ "\tpackage version: #{PKG_VERSION}\n",
284
+ "\tfiles: " + files.collect {|f| f.to_s }.join(', ') + "\n"
285
+
286
+ ask_for_confirmation( "Publish to RubyForge?" ) do
287
+ log 'Logging in...'
288
+ rf.login
289
+ log "Adding the new release to the '#{project}' project"
290
+ rf.add_release( group_id, package_id, PKG_VERSION, *files )
291
+ end
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
297
+
298
+ rescue LoadError => err
299
+ if !Object.const_defined?( :Gem )
300
+ require 'rubygems'
301
+ retry
302
+ end
303
+
304
+ task :no_release_tasks do
305
+ fail "Release tasks not defined: #{err.message}"
306
+ end
307
+
308
+ task :release => :no_release_tasks
309
+ task "release:announce" => :no_release_tasks
310
+ task "release:publish" => :no_release_tasks
311
+ task "release:notes" => :no_release_tasks
312
+ end
313
+
314
+ desc "Package up a release, publish it, and send out notifications"
315
+ task :release => 'release:default'
316
+ task :rerelease => 'release:rerelease'
317
+ task :testrelease => 'release:test'
318
+