menutree 0.0.3
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/.gitignore +1 -0
- data/README +49 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/lib/base.rb +86 -0
- data/lib/menutree.rb +5 -0
- data/menutree.gemspec +47 -0
- metadata +82 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/
|
data/README
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Menutree
|
2
|
+
|
3
|
+
Menutree is a framework for presenting a recursive menu shell on the command
|
4
|
+
line, inspired by the CLI found in Cisco IOS and other similar products.
|
5
|
+
Menutree lets users issue commands via an interactive nested shell interface,
|
6
|
+
and also directly from the command line.
|
7
|
+
|
8
|
+
The menu structure and commands therein are defined by a directory of ruby
|
9
|
+
scripts conforming to a simple interface. Inline help, command completion, and
|
10
|
+
readline support are all built in.
|
11
|
+
|
12
|
+
## Example:
|
13
|
+
|
14
|
+
Given a hypothetical program 'ticker' that uses the Menutree gem to manage a list of
|
15
|
+
tickets, a sample interaction might look like:
|
16
|
+
|
17
|
+
<pre>
|
18
|
+
$ ticker
|
19
|
+
> init
|
20
|
+
Ticker created an empty ticket database
|
21
|
+
> add "Do a little dance"
|
22
|
+
Ticket "Do a little dance" added as ticket 213
|
23
|
+
> rm
|
24
|
+
rm> 213
|
25
|
+
Ticket 213 ("Do a little dance") removed
|
26
|
+
rm> ..
|
27
|
+
> exit
|
28
|
+
</pre>
|
29
|
+
|
30
|
+
Commands could also be run from the shell:
|
31
|
+
|
32
|
+
<pre>
|
33
|
+
$ ticker add "Make a little love"
|
34
|
+
Ticket "Make a little love" added as ticket 214
|
35
|
+
</pre>
|
36
|
+
|
37
|
+
To implement this, ticker would provide Menutree with a directory that looked
|
38
|
+
like:
|
39
|
+
|
40
|
+
<pre>
|
41
|
+
commands/
|
42
|
+
init.rb
|
43
|
+
add/
|
44
|
+
default.rb
|
45
|
+
rm/
|
46
|
+
default.rb
|
47
|
+
</pre>
|
48
|
+
|
49
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rcov/rcovtask'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |s|
|
8
|
+
s.name = "menutree"
|
9
|
+
s.summary = "a simple hierachical command line shell"
|
10
|
+
s.description = "Menutree is a framework for presenting a recursive menu shell on the command
|
11
|
+
line, inspired by the CLI found in Cisco IOS and similar products"
|
12
|
+
s.email = "mat@geeky.net"
|
13
|
+
s.homepage = "http://github.com/mtrudel/menutree"
|
14
|
+
s.authors = ["Mat Trude", "Grant McInnes"]
|
15
|
+
s.add_dependency 'activesupport'
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::TestTask.new do |t|
|
23
|
+
t.libs << 'lib'
|
24
|
+
t.pattern = 'test/**/*_test.rb'
|
25
|
+
t.verbose = false
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'yard'
|
30
|
+
YARD::Rake::YardocTask.new(:yardoc)
|
31
|
+
rescue LoadError
|
32
|
+
task :yardoc do
|
33
|
+
abort "YARD is not available. In order to run yard, you must: sudo gem install yard"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
Rcov::RcovTask.new do |t|
|
39
|
+
t.libs << "test"
|
40
|
+
t.test_files = FileList['test/*_test.rb']
|
41
|
+
t.verbose = true
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
task :default => :rcov
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.3
|
data/lib/base.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'readline'
|
2
|
+
require 'active_support'
|
3
|
+
|
4
|
+
class MenuTree
|
5
|
+
attr_accessor :directory
|
6
|
+
attr_accessor :parent
|
7
|
+
attr_accessor :prompt
|
8
|
+
|
9
|
+
def initialize(directory, parent = "")
|
10
|
+
@directory = directory
|
11
|
+
@parent = parent
|
12
|
+
if @parent.is_a? self.class
|
13
|
+
@prompt = @parent.prompt + "/" + File.basename(@directory)
|
14
|
+
else
|
15
|
+
@prompt = @parent
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def run_command(cmds)
|
20
|
+
Readline.completion_append_character = " "
|
21
|
+
Readline.completion_proc = Proc.new do |str|
|
22
|
+
commands(str)
|
23
|
+
end
|
24
|
+
|
25
|
+
one_shot = true unless cmds.empty?
|
26
|
+
to_run = cmds.shift
|
27
|
+
while true do
|
28
|
+
if (to_run.nil?)
|
29
|
+
cmds = Readline.readline("#{@prompt}> ", true).split
|
30
|
+
to_run = cmds.shift
|
31
|
+
end
|
32
|
+
|
33
|
+
# If it's a builtin, run it
|
34
|
+
if (to_run.nil?)
|
35
|
+
next
|
36
|
+
elsif (to_run == "help" or to_run == "?")
|
37
|
+
display_help
|
38
|
+
elsif (to_run == "quit")
|
39
|
+
exit
|
40
|
+
elsif (to_run == "..")
|
41
|
+
return
|
42
|
+
elsif File.exists?(File.join(@directory, "#{to_run}.rb"))
|
43
|
+
# If we have a .rb file, run it with the rest of cmd as arguments
|
44
|
+
# TODO -- use .extend?
|
45
|
+
require File.join(@directory, "#{to_run}")
|
46
|
+
eval(to_run.camelize).new.run(cmds)
|
47
|
+
elsif File.directory?(File.join(@directory, to_run))
|
48
|
+
menu = MenuTree.new(File.join(@directory, to_run), self)
|
49
|
+
menu.run_command(cmds)
|
50
|
+
elsif File.exists?(File.join(@directory, "default.rb"))
|
51
|
+
# TODO let default handle it, allowing us to have proxy menus
|
52
|
+
else
|
53
|
+
puts "Unknown command #{to_run}"
|
54
|
+
end
|
55
|
+
to_run = nil
|
56
|
+
return if one_shot
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def commands(prefix='')
|
61
|
+
completions = []
|
62
|
+
Dir.new(@directory).each do |command|
|
63
|
+
if command =~ /^[^\.]/ and command =~ /^#{Regexp.escape(prefix)}/ and File.file?(File.join(@directory, command))
|
64
|
+
completions << File.basename(command, '.rb')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
completions
|
68
|
+
end
|
69
|
+
|
70
|
+
def display_help
|
71
|
+
puts <<EOF
|
72
|
+
Builtin commands:
|
73
|
+
help:\t\t\t\tDisplays this message
|
74
|
+
quit:\t\t\t\tQuits this session
|
75
|
+
..: \t\t\t\tGoes up a level in the menu (or quits if at the root)
|
76
|
+
|
77
|
+
#{@parent} commands:
|
78
|
+
EOF
|
79
|
+
|
80
|
+
# TODO display some help for each submenu
|
81
|
+
commands.each do |cmd|
|
82
|
+
require File.join(@directory, "#{cmd}")
|
83
|
+
puts " #{cmd}:\t\t\t\t#{eval(cmd.camelize).new.description}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/menutree.rb
ADDED
data/menutree.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{menutree}
|
8
|
+
s.version = "0.0.3"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Mat Trude", "Grant McInnes"]
|
12
|
+
s.date = %q{2010-03-16}
|
13
|
+
s.description = %q{Menutree is a framework for presenting a recursive menu shell on the command
|
14
|
+
line, inspired by the CLI found in Cisco IOS and similar products}
|
15
|
+
s.email = %q{mat@geeky.net}
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"README"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"README",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"lib/base.rb",
|
25
|
+
"lib/menutree.rb",
|
26
|
+
"menutree.gemspec"
|
27
|
+
]
|
28
|
+
s.homepage = %q{http://github.com/mtrudel/menutree}
|
29
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
30
|
+
s.require_paths = ["lib"]
|
31
|
+
s.rubygems_version = %q{1.3.6}
|
32
|
+
s.summary = %q{a simple hierachical command line shell}
|
33
|
+
|
34
|
+
if s.respond_to? :specification_version then
|
35
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
36
|
+
s.specification_version = 3
|
37
|
+
|
38
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
39
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
40
|
+
else
|
41
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
42
|
+
end
|
43
|
+
else
|
44
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: menutree
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Mat Trude
|
13
|
+
- Grant McInnes
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-03-16 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activesupport
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
description: |-
|
34
|
+
Menutree is a framework for presenting a recursive menu shell on the command
|
35
|
+
line, inspired by the CLI found in Cisco IOS and similar products
|
36
|
+
email: mat@geeky.net
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- README
|
46
|
+
- Rakefile
|
47
|
+
- VERSION
|
48
|
+
- lib/base.rb
|
49
|
+
- lib/menutree.rb
|
50
|
+
- menutree.gemspec
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/mtrudel/menutree
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --charset=UTF-8
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.6
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: a simple hierachical command line shell
|
81
|
+
test_files: []
|
82
|
+
|