treequel-shell 1.10.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.tar.gz.sig +0 -0
- data/ChangeLog +620 -0
- data/History.rdoc +7 -0
- data/Manifest.txt +8 -0
- data/README.rdoc +61 -0
- data/Rakefile +58 -0
- data/bin/treeirb +18 -0
- data/bin/treequel +1231 -0
- data/bin/treewhat +397 -0
- metadata +238 -0
- metadata.gz.sig +1 -0
data/bin/treewhat
ADDED
@@ -0,0 +1,397 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'abbrev'
|
5
|
+
require 'trollop'
|
6
|
+
require 'highline'
|
7
|
+
require 'shellwords'
|
8
|
+
require 'loggability'
|
9
|
+
|
10
|
+
# Work around MacOS X's vendored 'sysexits' that does the same thing,
|
11
|
+
# but with a different API
|
12
|
+
gem 'sysexits'
|
13
|
+
require 'sysexits'
|
14
|
+
|
15
|
+
require 'treequel'
|
16
|
+
require 'treequel/mixins'
|
17
|
+
require 'treequel/constants'
|
18
|
+
|
19
|
+
|
20
|
+
# A tool for displaying information about a directory's records and schema artifacts.
|
21
|
+
class Treequel::What
|
22
|
+
extend Sysexits,
|
23
|
+
Loggability
|
24
|
+
include Sysexits,
|
25
|
+
Treequel::ANSIColorUtilities,
|
26
|
+
Treequel::Constants::Patterns,
|
27
|
+
Treequel::HashUtilities
|
28
|
+
|
29
|
+
# Loggability API -- log to Treequel's logger
|
30
|
+
log_to :treequel
|
31
|
+
|
32
|
+
|
33
|
+
# Highline color scheme
|
34
|
+
COLOR_SCHEME = HighLine::ColorScheme.new do |scheme|
|
35
|
+
scheme[:header] = [ :bold, :yellow ]
|
36
|
+
scheme[:subheader] = [ :bold, :white ]
|
37
|
+
scheme[:key] = [ :white ]
|
38
|
+
scheme[:value] = [ :bold, :white ]
|
39
|
+
scheme[:error] = [ :red ]
|
40
|
+
scheme[:warning] = [ :yellow ]
|
41
|
+
scheme[:message] = [ :reset ]
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
### Run the utility with the given +args+.
|
46
|
+
def self::run( args )
|
47
|
+
HighLine.color_scheme = COLOR_SCHEME
|
48
|
+
|
49
|
+
oparser = self.make_option_parser
|
50
|
+
opts = Trollop.with_standard_exception_handling( oparser ) do
|
51
|
+
oparser.parse( args )
|
52
|
+
end
|
53
|
+
|
54
|
+
pattern = oparser.leftovers.join( ' ' ) if oparser.leftovers
|
55
|
+
|
56
|
+
self.new( opts ).run( pattern )
|
57
|
+
exit :ok
|
58
|
+
|
59
|
+
rescue => err
|
60
|
+
self.log.fatal "Oops: %s: %s" % [ err.class.name, err.message ]
|
61
|
+
self.log.debug { ' ' + err.backtrace.join("\n ") }
|
62
|
+
|
63
|
+
exit :software_error
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
### Create and configure a command-line option parser (a Trollop::Parser) for the command.
|
68
|
+
def self::make_option_parser
|
69
|
+
progname = File.basename( $0 )
|
70
|
+
default_directory = Treequel.directory_from_config
|
71
|
+
loglevels = Loggability::LOG_LEVELS.keys.join( ', ' )
|
72
|
+
|
73
|
+
return Trollop::Parser.new do
|
74
|
+
banner "Usage: #{progname} [OPTIONS] [PATTERN]"
|
75
|
+
|
76
|
+
text ''
|
77
|
+
text %{Search for an object in an LDAP directory that matches PATTERN and } +
|
78
|
+
%{display some information about it.}
|
79
|
+
text ''
|
80
|
+
text %{The PATTERN can be the DN (or RDN relative to the base) of an entry, } +
|
81
|
+
%{a search filter, or the name of an artifact in the directory's schema, } +
|
82
|
+
%{such as an objectClass, matching rule, syntax, etc.}
|
83
|
+
text ''
|
84
|
+
text %{If no PATTERN is specified, general information about the directory is } +
|
85
|
+
%{output instead.}
|
86
|
+
text ''
|
87
|
+
|
88
|
+
text 'Connection Options:'
|
89
|
+
opt :ldapurl, "Specify the directory to connect to.",
|
90
|
+
:default => default_directory.uri.to_s
|
91
|
+
text ''
|
92
|
+
|
93
|
+
text 'Display Options:'
|
94
|
+
opt :attrtypes, "Show attribute types for objects that have them."
|
95
|
+
opt :objectclasses, "Show objectclasses for objects that have them."
|
96
|
+
opt :syntaxes, "Show syntaxes for objects that have them."
|
97
|
+
opt :matching_rules, "Show matching rules for objects that have them."
|
98
|
+
opt :matching_rule_uses, "Show matching rule uses for objects that have them."
|
99
|
+
opt :all, "Show any of the above that are applicable."
|
100
|
+
text ''
|
101
|
+
|
102
|
+
text 'Other Options:'
|
103
|
+
opt :debug, "Turn debugging on. Also sets the --loglevel to 'debug'."
|
104
|
+
opt :loglevel, "Set the logging level. Must be one of: #{loglevels}",
|
105
|
+
:default => Loggability[ Treequel ].level.to_s
|
106
|
+
opt :binddn, "The DN of the user to bind as. Defaults to anonymous binding.",
|
107
|
+
:type => :string
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
#################################################################
|
113
|
+
### I N S T A N C E M E T H O D S
|
114
|
+
#################################################################
|
115
|
+
|
116
|
+
### Create a new instance of the command and set it up with the given
|
117
|
+
### +options+.
|
118
|
+
def initialize( options )
|
119
|
+
Loggability.format_with( :color ) if $stderr.tty?
|
120
|
+
|
121
|
+
if options.debug
|
122
|
+
$DEBUG = true
|
123
|
+
$VERBOSE = true
|
124
|
+
Loggability.level = :debug
|
125
|
+
elsif options.loglevel
|
126
|
+
Loggability.level = options.loglevel
|
127
|
+
end
|
128
|
+
|
129
|
+
@options = options
|
130
|
+
if @options.all?
|
131
|
+
@options[:attrtypes] =
|
132
|
+
@options[:objectclasses] =
|
133
|
+
@options[:syntaxes] =
|
134
|
+
@options[:matching_rules] =
|
135
|
+
@options[:matching_rule_uses] =
|
136
|
+
true
|
137
|
+
end
|
138
|
+
|
139
|
+
@directory = Treequel.directory( options.ldapurl )
|
140
|
+
@prompt = HighLine.new
|
141
|
+
|
142
|
+
@prompt.wrap_at = @prompt.output_cols - 10
|
143
|
+
|
144
|
+
self.log.debug "Created new treewhat command object for %s" % [ @directory ]
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
######
|
149
|
+
public
|
150
|
+
######
|
151
|
+
|
152
|
+
# The LDAP directory the command will connect to
|
153
|
+
attr_reader :directory
|
154
|
+
|
155
|
+
# The Trollop options hash the command will read its configuration from
|
156
|
+
attr_reader :options
|
157
|
+
|
158
|
+
# The HighLine object to use for prompting and displaying stuff
|
159
|
+
attr_reader :prompt
|
160
|
+
|
161
|
+
|
162
|
+
### Display an +object+ highlighted as a header.
|
163
|
+
def print_header( object )
|
164
|
+
self.prompt.say( self.prompt.color(object.to_s, :header) )
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
### Run the command with the specified +pattern+.
|
169
|
+
def run( pattern=nil )
|
170
|
+
self.log.debug "Running with pattern = %p" % [ pattern ]
|
171
|
+
|
172
|
+
self.bind_to_directory if self.options.binddn
|
173
|
+
|
174
|
+
case pattern
|
175
|
+
|
176
|
+
# No argument
|
177
|
+
when NilClass, ''
|
178
|
+
self.show_directory_overview
|
179
|
+
|
180
|
+
# DN/RDN or filter if it contains a '='
|
181
|
+
when %r/=/
|
182
|
+
self.show_entry( pattern )
|
183
|
+
|
184
|
+
# Otherwise, try to find a schema item that matches
|
185
|
+
else
|
186
|
+
self.show_schema_artifact( pattern )
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
### Prompt for a password and then bind to the command's directory using the binddn in
|
193
|
+
### the options.
|
194
|
+
def bind_to_directory
|
195
|
+
binddn = self.options.binddn or
|
196
|
+
raise ArgumentError, "no binddn in the options hash?!"
|
197
|
+
self.log.debug "Attempting to bind to the directory as %s" % [ binddn ]
|
198
|
+
|
199
|
+
pass = self.prompt.ask( "password: " ) {|q| q.echo = '*' }
|
200
|
+
user = Treequel::Branch.new( self.directory, binddn )
|
201
|
+
|
202
|
+
self.directory.bind_as( user, pass )
|
203
|
+
self.log.debug " bound as %s" % [ user ]
|
204
|
+
|
205
|
+
return true
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
### Show general information about the directory if the user doesn't give a pattern on
|
210
|
+
### the command line.
|
211
|
+
def show_directory_overview
|
212
|
+
pr = self.prompt
|
213
|
+
dir = self.directory
|
214
|
+
|
215
|
+
self.print_header( dir.uri.to_s )
|
216
|
+
pr.say( "\n" )
|
217
|
+
pr.say( dir.schema.to_s )
|
218
|
+
|
219
|
+
self.show_column_list( dir.schema.attribute_types.values, 'Attribute Types' ) if
|
220
|
+
self.options.attrtypes
|
221
|
+
self.show_column_list( dir.schema.object_classes.values, "Object Classes" ) if
|
222
|
+
self.options.objectclasses
|
223
|
+
self.show_column_list( dir.schema.ldap_syntaxes.values, "Syntaxes" ) if
|
224
|
+
self.options.syntaxes
|
225
|
+
self.show_column_list( dir.schema.matching_rules.values, "Matching Rules" ) if
|
226
|
+
self.options.matching_rules
|
227
|
+
self.show_column_list( dir.schema.matching_rule_uses.values, "Matching Rule Uses" ) if
|
228
|
+
self.options.matching_rule_uses
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
### Show the items from the given +enum+ under the specified +subheading+ in a columnized list.
|
233
|
+
def show_column_list( enum, subheading )
|
234
|
+
pr = self.prompt
|
235
|
+
items = nil
|
236
|
+
|
237
|
+
if enum.first.respond_to?( :name )
|
238
|
+
items = enum.map( &:name ).map( &:to_s ).uniq
|
239
|
+
else
|
240
|
+
items = enum.map( &:oid ).uniq
|
241
|
+
end
|
242
|
+
|
243
|
+
pr.say( "\n" )
|
244
|
+
pr.say( pr.color(subheading, :subheader) )
|
245
|
+
pr.say( pr.list(items.sort_by(&:downcase), :columns_down) )
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
#
|
250
|
+
# 'Show entry' mode
|
251
|
+
#
|
252
|
+
|
253
|
+
### Fetch an entry from the directory and display it like Treequel's editing mode.
|
254
|
+
def show_entry( pattern )
|
255
|
+
dir = self.directory
|
256
|
+
branch = Treequel::Branch.new( dir, pattern )
|
257
|
+
|
258
|
+
if !branch.exists?
|
259
|
+
branch = Treequel::Branch.new( dir, pattern + ',' + dir.base_dn )
|
260
|
+
end
|
261
|
+
|
262
|
+
if !branch.exists?
|
263
|
+
branch = dir.filter( pattern ).first
|
264
|
+
end
|
265
|
+
|
266
|
+
if !branch
|
267
|
+
self.prompt.say( self.prompt.color("No match.", :error) )
|
268
|
+
end
|
269
|
+
|
270
|
+
yaml = self.branch_as_yaml( branch )
|
271
|
+
self.prompt.say( yaml )
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
### Return the specified Treequel::Branch object as YAML. If +include_operational+ is true,
|
276
|
+
### include the entry's operational attributes. If +extra_objectclasses+ contains
|
277
|
+
### one or more objectClass OIDs, include their MUST and MAY attributes when building the
|
278
|
+
### YAML representation of the branch.
|
279
|
+
def branch_as_yaml( object, include_operational=false )
|
280
|
+
object.include_operational_attrs = include_operational
|
281
|
+
|
282
|
+
# Make sure the displayed entry has the MUST attributes
|
283
|
+
entryhash = stringify_keys( object.must_attributes_hash )
|
284
|
+
entryhash.merge!( object.entry || {} )
|
285
|
+
entryhash['objectClass'] ||= []
|
286
|
+
|
287
|
+
entryhash.delete( 'dn' ) # Special attribute, can't be edited
|
288
|
+
|
289
|
+
yaml = entryhash.to_yaml
|
290
|
+
yaml[ 5, 0 ] = self.prompt.color( "# #{object.dn}\n", :header )
|
291
|
+
|
292
|
+
# Make comments out of MAY attributes that are unset
|
293
|
+
mayhash = stringify_keys( object.may_attributes_hash )
|
294
|
+
self.log.debug "MAY hash is: %p" % [ mayhash ]
|
295
|
+
mayhash.delete_if {|attrname,val| entryhash.key?(attrname) }
|
296
|
+
yaml << mayhash.to_yaml[5..-1].gsub( /\n\n/, "\n" ).gsub( /^/, '# ' )
|
297
|
+
|
298
|
+
return yaml
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
#
|
305
|
+
# 'Show schema artifact' mode
|
306
|
+
#
|
307
|
+
|
308
|
+
SCHEMA_ARTIFACT_TYPES = [
|
309
|
+
:object_classes,
|
310
|
+
:attribute_types,
|
311
|
+
:ldap_syntaxes,
|
312
|
+
:matching_rules,
|
313
|
+
:matching_rule_uses,
|
314
|
+
]
|
315
|
+
|
316
|
+
### Find an artifact in the directory's schema that matches +pattern+, and display it
|
317
|
+
### if it exists.
|
318
|
+
def show_schema_artifact( pattern )
|
319
|
+
pr = self.prompt
|
320
|
+
schema = self.directory.schema
|
321
|
+
artifacts = SCHEMA_ARTIFACT_TYPES.
|
322
|
+
collect {|type| schema.send( type ).values.uniq }.flatten
|
323
|
+
|
324
|
+
if match = find_exact_matching_artifact( artifacts, pattern )
|
325
|
+
self.display_schema_artifact( match )
|
326
|
+
elsif match = find_substring_matching_artifact( artifacts, pattern )
|
327
|
+
pr.say( "No exact match. Falling back to substring match:" )
|
328
|
+
self.display_schema_artifact( match )
|
329
|
+
else
|
330
|
+
pr.say( pr.color("No match.", :error) )
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
### Display a schema artifact in a readable way.
|
336
|
+
def display_schema_artifact( artifact )
|
337
|
+
self.prompt.say( self.prompt.color(artifact.class.name.sub(/.*::/, ''), :header) + ' ' )
|
338
|
+
self.prompt.say( self.prompt.color(artifact.to_s, :subheader) )
|
339
|
+
|
340
|
+
# Display some other stuff depending on what kind of thing it is
|
341
|
+
case artifact
|
342
|
+
when Treequel::Schema::AttributeType
|
343
|
+
self.display_attrtype_details( artifact )
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
|
348
|
+
### Display additional details for the specified +attrtype+ (a Treequel::Schema::AttributeType).
|
349
|
+
def display_attrtype_details( attrtype )
|
350
|
+
ocs = self.directory.schema.object_classes.values.find_all do |oc|
|
351
|
+
( oc.must_oids | oc.may_oids ).include?( attrtype.name.to_sym )
|
352
|
+
end
|
353
|
+
|
354
|
+
if ocs.empty?
|
355
|
+
self.prompt.say "No objectClasses with the '%s' attribute are in the current schema." %
|
356
|
+
[ attrtype.name ]
|
357
|
+
else
|
358
|
+
ocnames = ocs.uniq.map( &:name ).map( &:to_s ).sort
|
359
|
+
|
360
|
+
self.prompt.say "objectClasses with the '%s' attribute in the current schema:" %
|
361
|
+
[ attrtype.name ]
|
362
|
+
self.prompt.say( self.prompt.list(ocnames, :columns_across) )
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
|
367
|
+
### Try to find an artifact in +artifacts+ whose name or oid matches +pattern+ exactly.
|
368
|
+
### Returns the first matching artifact.
|
369
|
+
def find_exact_matching_artifact( artifacts, pattern )
|
370
|
+
self.log.debug "Trying to find an exact match for %p in %d artifacts." %
|
371
|
+
[ pattern, artifacts.length ]
|
372
|
+
return artifacts.find do |obj|
|
373
|
+
(obj.respond_to?( :names ) && obj.names.map(&:to_s).include?(pattern) ) ||
|
374
|
+
(obj.respond_to?( :name ) && obj.name.to_s == pattern ) ||
|
375
|
+
(obj.respond_to?( :oid ) && obj.oid == pattern )
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
|
380
|
+
### Try to find an artifact in +artifacts+ whose name or oid contains +pattern+.
|
381
|
+
### Returns the first matching artifact.
|
382
|
+
def find_substring_matching_artifact( artifacts, pattern )
|
383
|
+
pattern = Regexp.new( Regexp.escape(pattern), Regexp::IGNORECASE )
|
384
|
+
|
385
|
+
return artifacts.find do |obj|
|
386
|
+
(obj.respond_to?( :names ) && obj.names.find {|name| name.to_s =~ pattern} ) ||
|
387
|
+
(obj.respond_to?( :name ) && obj.name.to_s =~ pattern ) ||
|
388
|
+
(obj.respond_to?( :oid ) && obj.oid =~ pattern )
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
|
393
|
+
end # class Treequel::What
|
394
|
+
|
395
|
+
|
396
|
+
Treequel::What.run( ARGV.dup )
|
397
|
+
|
metadata
ADDED
@@ -0,0 +1,238 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: treequel-shell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.10.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michael Granger
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain:
|
12
|
+
- !binary |-
|
13
|
+
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMRENDQWhTZ0F3SUJB
|
14
|
+
Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREE4TVF3d0NnWURWUVFEREFOblpX
|
15
|
+
UXgKRnpBVkJnb0praWFKay9Jc1pBRVpGZ2RmWVdWeWFXVmZNUk13RVFZS0Na
|
16
|
+
SW1pWlB5TEdRQkdSWURiM0puTUI0WApEVEV3TURreE5qRTBORGcxTVZvWERU
|
17
|
+
RXhNRGt4TmpFME5EZzFNVm93UERFTU1Bb0dBMVVFQXd3RFoyVmtNUmN3CkZR
|
18
|
+
WUtDWkltaVpQeUxHUUJHUllIWDJGbGNtbGxYekVUTUJFR0NnbVNKb21UOGl4
|
19
|
+
a0FSa1dBMjl5WnpDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURD
|
20
|
+
Q0FRb0NnZ0VCQUx5Ly9CRnhDMWYvY1BTbnd0SkJXb0ZpRnJpcgpoN1JpY0kr
|
21
|
+
am9xL29jVlhRcUk0VERXUHlGLzh0cWt2dCtyRDk5WDlxczJZZVI4Q1UvWWlJ
|
22
|
+
cExXclFPWVNUNzBKCnZEbjdVdmhiMm11RlZxcTYrdm9iZVRrSUxCRU82cGlv
|
23
|
+
bldERzhqU2JvM3FLbTFSaktKRHdnOXA0d05LaFB1dTgKS0d1ZS9CRmI2N0tm
|
24
|
+
bHF5QXBQbVBlYjNWZGQ5Y2xzcHpxZUZxcDdjVUJNRXBGUzZMV3h5NEdrK3F2
|
25
|
+
RkZKQkpMQgpCVUhFL0xaVkpNVnpmcEM1VXErUW1ZN0IrRkgvUXFObmRuM3RP
|
26
|
+
SGdzUGFkTFROaW11QjFzQ3VMMWE0ejNQZXBkClRlTEJFRm1FYW81RGszSy9R
|
27
|
+
OG84dmxiSUIvakJEVFV4NkRqYmd4dzc3OTA5eDZnSTlkb1U0TEQ1WE1jQ0F3
|
28
|
+
RUEKQWFNNU1EY3dDUVlEVlIwVEJBSXdBREFMQmdOVkhROEVCQU1DQkxBd0hR
|
29
|
+
WURWUjBPQkJZRUZKZW9Ha09yOWw0Qgorc2FNa1cvWlhUNFVlU3ZWTUEwR0NT
|
30
|
+
cUdTSWIzRFFFQkJRVUFBNElCQVFCRzJLT2J2WUkyZUh5eUJVSlNKM2pOCnZF
|
31
|
+
blUzZDYwem5BWGJyU2QycWIzcjFsWTFFUEREM2JjeTBNZ2dDZkdkZzNYdTU0
|
32
|
+
ejIxb3F5SWRrOHVHdFdCUEwKSElhOUVnZkZHU1VFZ3ZjSXZhWXFpTjRqVFV0
|
33
|
+
aWRmRUZ3K0x0anM4QVA5Z1dnU0lZUzZHcjM4VjBXR0ZGTnpJSAphT0Qyd211
|
34
|
+
OW9vL1JmZlc0aFMvOEd1dmZNemN3N0NRMzU1d0ZSNEtCL255emUrRXNaMVk1
|
35
|
+
RGVyQ0FhZ01WdURRClUwQkxtV0RGelBHR1dsUGVRQ3JZSENyK0FjSnorTlJu
|
36
|
+
YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
|
37
|
+
Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
|
38
|
+
cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
39
|
+
date: 2012-08-29 00:00:00.000000000 Z
|
40
|
+
dependencies:
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: loggability
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.5'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ~>
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0.5'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: treequel
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ~>
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '1.10'
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ~>
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '1.10'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: highline
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ~>
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '1.6'
|
81
|
+
type: :runtime
|
82
|
+
prerelease: false
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ~>
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.6'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: trollop
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.0'
|
97
|
+
type: :runtime
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ~>
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '2.0'
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: sysexits
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ~>
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '1.0'
|
113
|
+
type: :runtime
|
114
|
+
prerelease: false
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ~>
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '1.0'
|
121
|
+
- !ruby/object:Gem::Dependency
|
122
|
+
name: hoe-mercurial
|
123
|
+
requirement: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ~>
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 1.4.0
|
129
|
+
type: :development
|
130
|
+
prerelease: false
|
131
|
+
version_requirements: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ~>
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: 1.4.0
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: hoe-highline
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ~>
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 0.1.0
|
145
|
+
type: :development
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
none: false
|
149
|
+
requirements:
|
150
|
+
- - ~>
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.1.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rdoc
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
none: false
|
157
|
+
requirements:
|
158
|
+
- - ~>
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '3.10'
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ~>
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '3.10'
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: hoe
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
none: false
|
173
|
+
requirements:
|
174
|
+
- - ~>
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '3.0'
|
177
|
+
type: :development
|
178
|
+
prerelease: false
|
179
|
+
version_requirements: !ruby/object:Gem::Requirement
|
180
|
+
none: false
|
181
|
+
requirements:
|
182
|
+
- - ~>
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '3.0'
|
185
|
+
description: ! "Treequel-Shell is a collection of LDAP tools based on the Treequel
|
186
|
+
LDAP\ntoolkit.\n\nIt includes:\n\ntreequel :: an LDAP shell/editor; treat your LDAP
|
187
|
+
directory like a filesystem!\ntreewhat :: an LDAP schema explorer. Dump objectClasses
|
188
|
+
and attribute type info\n in several convenient formats."
|
189
|
+
email:
|
190
|
+
- ged@FaerieMUD.org
|
191
|
+
executables:
|
192
|
+
- treeirb
|
193
|
+
- treequel
|
194
|
+
- treewhat
|
195
|
+
extensions: []
|
196
|
+
extra_rdoc_files:
|
197
|
+
- History.rdoc
|
198
|
+
- Manifest.txt
|
199
|
+
- README.rdoc
|
200
|
+
files:
|
201
|
+
- ChangeLog
|
202
|
+
- History.rdoc
|
203
|
+
- Manifest.txt
|
204
|
+
- README.rdoc
|
205
|
+
- Rakefile
|
206
|
+
- bin/treeirb
|
207
|
+
- bin/treequel
|
208
|
+
- bin/treewhat
|
209
|
+
homepage: https://bitbucket.org/ged/Treequel-Shell
|
210
|
+
licenses:
|
211
|
+
- BSD
|
212
|
+
post_install_message:
|
213
|
+
rdoc_options:
|
214
|
+
- -f
|
215
|
+
- fivefish
|
216
|
+
- -t
|
217
|
+
- Treequel
|
218
|
+
require_paths:
|
219
|
+
- lib
|
220
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
221
|
+
none: false
|
222
|
+
requirements:
|
223
|
+
- - ! '>='
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: 1.8.7
|
226
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
|
+
none: false
|
228
|
+
requirements:
|
229
|
+
- - ! '>='
|
230
|
+
- !ruby/object:Gem::Version
|
231
|
+
version: '0'
|
232
|
+
requirements: []
|
233
|
+
rubyforge_project: treequel-shell
|
234
|
+
rubygems_version: 1.8.24
|
235
|
+
signing_key:
|
236
|
+
specification_version: 3
|
237
|
+
summary: Treequel-Shell is a collection of LDAP tools based on the Treequel LDAP toolkit
|
238
|
+
test_files: []
|