treequel-shell 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|