arsh 1.0.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.
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env ruby
2
+ ARSH_INSTALL_PATH=File.expand_path("../../",__FILE__)
3
+ require 'rb-readline'
4
+
5
+ Dir.glob("#{ARSH_INSTALL_PATH}/libs/*.rb").each { |mod| load(mod) }
6
+ trap('QUIT',"IGNORE")
7
+ trap('INT') do
8
+ begin
9
+ break
10
+ rescue
11
+ print "^C"
12
+ end
13
+ end
14
+ ## Set up some default variables
15
+ $ps1="(arsh)<% ENV['USER'] %>@<% Dir.pwd %>$ "
16
+ $ps2=">"
17
+
18
+ ## Setup readline's completion
19
+ Readline.completion_append_character = nil
20
+ Readline.completion_proc = lambda do |search|
21
+ # Complete files and directories
22
+ # Complete programs and files within the path.
23
+ files = []
24
+ case search
25
+ when ""
26
+ files = ArshCommands.search_current_directory(files,search)
27
+ files = ArshCommands.search_path(files)
28
+ else
29
+ files = ArshCommands.search_current_directory(files,search)
30
+ if files.select { |f| f =~ %r[^#{search}] }.empty?
31
+ files = ArshCommands.search_path(files)
32
+ end
33
+ end
34
+ # Complete builtin methods
35
+ ArshCommands.singleton_methods.each { |method| files << method if method =~ /^#{search}/ }
36
+ files.uniq
37
+ files = files.select { |f| f =~ %r[^#{search}] }
38
+ end
39
+
40
+ # Builtin commands
41
+
42
+ module ArshCommands
43
+ INTHIST = Array.new
44
+ def internal_history
45
+ @internal_history
46
+ end
47
+ def internal_history=(input)
48
+ @internal_history << input
49
+ end
50
+ # Exit with exit code.
51
+ def self.exit(code)
52
+ Kernel.exit(code.to_s.to_i)
53
+ end
54
+
55
+ # Determine if a file is included in the path.
56
+ def self.in_path?(cmd,parms)
57
+ ENV['PATH'].split(/:/).each do |path|
58
+ if File.exists?("#{path}/#{cmd}") && File.executable?("#{path}/#{cmd}")
59
+ system("#{path}/#{cmd} #{parms.join(" ")}")
60
+ return true
61
+ end
62
+ end
63
+ return false
64
+ end
65
+
66
+ def self.parseinput(input)
67
+ cmd = input.split(/\s/)[0]
68
+ parms = replacestring(input).split(/\s/)[1..-1]
69
+ if ArshCommands.respond_to? cmd
70
+ begin
71
+ ArshCommands.send(replacestring(cmd),parms)
72
+ rescue
73
+ puts "#{$!}"
74
+ end
75
+ # If (full path) file is executable..
76
+ elsif File.exists?(cmd) && File.executable?(cmd)
77
+ system("#{cmd} #{parms}")
78
+ # If file is in PATH
79
+ elsif ArshCommands.in_path?(cmd,parms) == false
80
+ # Try to run input as ruby code.
81
+ ArshCommands.ruby_eval(input)
82
+ end
83
+ end
84
+
85
+ def self.search_current_directory(files,search)
86
+ Dir["#{search.gsub(%r[^/],"")}*"].each { |f| files << f }
87
+
88
+ files.map! { |f| f.gsub(%r[#{Dir.pwd}/],"") }.map! { |f| File.directory?(f) ? f + "/" : f }
89
+
90
+ return files
91
+ end
92
+
93
+ def self.search_path(files)
94
+ ENV['PATH'].split(":").each do |path|
95
+ begin
96
+ Dir.entries(path).each do |prog|
97
+ files << prog if File.executable?("#{path}/#{prog}")
98
+ end
99
+ rescue Errno::ENOENT
100
+ next
101
+ end
102
+ end
103
+ return files
104
+ end
105
+ end
106
+
107
+ # Load Plugins
108
+ begin
109
+ Dir.glob("#{ARSH_INSTALL_PATH}/plugins/*.rb").each { |plugin| require plugin }
110
+ rescue
111
+ puts "Error loading plugin: #{$!}"
112
+ end
113
+ # Main Loop
114
+
115
+ # Load rbshrc's
116
+ ["/etc/arshrc","#{ENV['HOME']}/.arshrc"].each do |arshrc|
117
+ File.open(arshrc,"r").readlines.each do |line|
118
+ ArshCommands.parseinput(line) if line != ""
119
+ end if File.exist?(arshrc)
120
+ end
121
+
122
+ while true
123
+
124
+ # Get input
125
+ begin
126
+ prompt = ArshCommands.rubyeval_indent == 0 ? $ps1 : "#{$ps2 * ArshCommands.rubyeval_indent} "
127
+ input = Readline::readline(ArshCommands.replacestring(prompt)).to_s.strip
128
+ rescue
129
+ puts ""
130
+ input = ""
131
+ end
132
+ next if input == "" # don't error on blank input
133
+ #begin puts input.gsub(/\#\{*\}/,'\1') rescue puts "#{$!}" end
134
+ Readline::HISTORY.push("#{input}") # Add command to history
135
+ ArshCommands::INTHIST.push("[#{Time.now.strftime("%a %b %d %H:%M:%S")}] #{input}")
136
+ # If command is builtin to shell...
137
+ ArshCommands.parseinput(input)
138
+ end
@@ -0,0 +1,21 @@
1
+ module ArshCommands
2
+ def self.alias(args)
3
+ args = args.join(" ")
4
+ alias_cmd, alias_body = args.split(/=/,2)
5
+ alias_body_cmd, alias_body_params = alias_body.split(/ /,2)
6
+ alias_cmd.strip!
7
+ alias_body_cmd.strip!
8
+ if alias_body_params != nil then
9
+ alias_body_params.strip
10
+ else
11
+ alias_body_params = ""
12
+ end
13
+ new_alias =<<-EOS
14
+ def self.#{alias_cmd}(args=[])
15
+ args = ["#{alias_body_params} "] + args
16
+ system("#{alias_body_cmd} \#{args.join(' ')}")
17
+ end
18
+ EOS
19
+ ArshCommands.module_eval(new_alias)
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module ArshCommands
2
+ # Change directory
3
+ def self.cd(dir)
4
+ dir = ["#{ENV['HOME']}"] if dir.nitems == 0
5
+ if File.directory?(File.expand_path(dir.join(" ")))
6
+ Dir.chdir(File.expand_path(dir.join(" ")))
7
+ elsif dir =~ /~/
8
+ dir.gsub("~","#{ENV['HOME']}")
9
+ else
10
+ puts "Invalid Directory #{dir.to_s}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/ruby
2
+ if ! String.respond_to?("each") then
3
+ class String
4
+ def each(splitter)
5
+ return self.split(splitter)
6
+ end
7
+ end
8
+ end
9
+
10
+ if ! Array.respond_to?("nitems") then
11
+ class Array
12
+ alias :nitems :count
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module ArshCommands
2
+ def self.replacestring(string)
3
+ @rep_new_string = string
4
+ begin
5
+ repstring = /<%(.*?)%>/.match(@rep_new_string)
6
+ loop do
7
+ rep_original = repstring[0]
8
+ rep_new = eval(repstring[1]).to_s
9
+ @rep_new_string = @rep_new_string.gsub(rep_original,rep_new)
10
+ repstring = /<%(.*?)%>/.match(@rep_new_string)
11
+ break if repstring == nil
12
+ end if /<%(.*?)%>/.match(@rep_new_string) != nil
13
+ rescue
14
+ puts $!
15
+ @rep_new_string.gsub!(repstring[0],"[ERR]")
16
+ end
17
+ return @rep_new_string
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # Evaluate ruby code typed into command line. Allow multiple lines of code before evaluting blcoks.
2
+ module ArshCommands
3
+ @rubyeval_proc = Proc.new {}
4
+ @rubyeval_indent = 0
5
+ @rubyeval_history = Array.new
6
+ def self.rubyeval_indent
7
+ return @rubyeval_indent
8
+ end
9
+ def self.ruby_eval(input)
10
+ # keywords that start a block
11
+ start_strings = ["class,","module","def","do","{","("]
12
+ # Keywords that end a block
13
+ end_strings = ["end","}",")"]
14
+ # Add last line typed to
15
+ @rubyeval_history << input
16
+ start_strings.each {|string| @rubyeval_indent += 1 if input.include? string}
17
+ end_strings.each {|string| @rubyeval_indent -=1 if input.include? string}
18
+ #input.strip.each(" ") {|string| @rubyeval_indent += 1 if start_strings.include? string }
19
+ #input.strip.each(" ") {|string| @rubyeval_indent -= 1 if end_strings.include? string }
20
+ if @rubyeval_indent <= 0
21
+ @rubyeval_indent = 0
22
+ begin
23
+ eval(@rubyeval_history.join("\n"),@rubyeval_proc.binding)
24
+ @rubyeval_history = Array.new
25
+ rescue ScriptError, StandardError
26
+ @rubyeval_history = Array.new
27
+ puts "#{$!}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Arsh
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,5 @@
1
+ module ArshCommands
2
+ def self.history(args)
3
+ puts ArshCommands::INTHIST.find_all { |x| puts x }
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ # ls.rb v0.1.0
2
+ # ls.rb - A partial implentation of ls all written in ruby.
3
+ #
4
+ # This example shows how easy it is to create a plugin for arsh.
5
+
6
+ # The ArshCommands module holds all internal commands.
7
+ module ArshCommands
8
+ def self.lsa(args = "")
9
+ directories = Dir.entries("#{Dir.pwd}").sort
10
+ directories.delete_if { |x| x =~ /^\./ unless args.include?("-a") }
11
+ directories.map! { |x| "#{("0x"+File.stat(x).mode.to_s)} #{File.stat(x).uid} #{File.stat(x).gid} #{File.stat(x).mtime} #{x} "} if args.include?("-l")
12
+ return directories
13
+ end
14
+ def self.lsx(args) # Each command is a method.
15
+ puts self.lsa(args)
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arsh
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Paterni
9
+ - Brian Faga
10
+ - Eugene Howe
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2011-12-22 00:00:00.000000000Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rb-readline
18
+ requirement: &9188080 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *9188080
27
+ description: Provides a shell that can run pure Ruby code as well as ordinary linux
28
+ commands.
29
+ email:
30
+ - james@ruby-code.com
31
+ - eugene@xtreme-computers.net
32
+ executables:
33
+ - arsh
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - bin/arsh
38
+ - plugins/ls.rb
39
+ - plugins/history.rb
40
+ - libs/replacestring.rb
41
+ - libs/compat.rb
42
+ - libs/rubyeval.rb
43
+ - libs/cd.rb
44
+ - libs/alias.rb
45
+ - libs/version.rb
46
+ homepage: http://github.com/jamez01/arsh
47
+ licenses: []
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: 1.3.6
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.10
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Linux shell implemented in pure Ruby
70
+ test_files: []