RubySH 1.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/RubySH-1.0.gem +0 -0
- data/bin/rsh +4 -0
- data/lib/rubysh.rb +3 -0
- data/lib/rubysh/colorize.rb +191 -0
- data/lib/rubysh/main.rb +141 -0
- data/lib/rubysh/utils.rb +6 -0
- data/rubysh.gemspec +17 -0
- metadata +56 -0
data/RubySH-1.0.gem
ADDED
File without changes
|
data/bin/rsh
ADDED
data/lib/rubysh.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
#
|
2
|
+
# Colorize String class extension. By fazibear (https://github.com/fazibear). Edited to have bold (bright) letters by Pablo Merino (https://github.com/pablo-merino)
|
3
|
+
#
|
4
|
+
class String
|
5
|
+
|
6
|
+
#
|
7
|
+
# Colors Hash
|
8
|
+
#
|
9
|
+
COLORS = {
|
10
|
+
:black => 0,
|
11
|
+
:red => 1,
|
12
|
+
:green => 2,
|
13
|
+
:yellow => 3,
|
14
|
+
:blue => 4,
|
15
|
+
:magenta => 5,
|
16
|
+
:cyan => 6,
|
17
|
+
:white => 7,
|
18
|
+
:default => 9,
|
19
|
+
|
20
|
+
:light_black => 10,
|
21
|
+
:light_red => 11,
|
22
|
+
:light_green => 12,
|
23
|
+
:light_yellow => 13,
|
24
|
+
:light_blue => 14,
|
25
|
+
:light_magenta => 15,
|
26
|
+
:light_cyan => 16,
|
27
|
+
:light_white => 17
|
28
|
+
}
|
29
|
+
|
30
|
+
#
|
31
|
+
# Modes Hash
|
32
|
+
#
|
33
|
+
MODES = {
|
34
|
+
:default => 0, # Turn off all attributes
|
35
|
+
:bright => 1, # Set bright mode
|
36
|
+
:underline => 4, # Set underline mode
|
37
|
+
:blink => 5, # Set blink mode
|
38
|
+
:swap => 7, # Exchange foreground and background colors
|
39
|
+
:hide => 8 # Hide text (foreground color would be the same as background)
|
40
|
+
}
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
#
|
45
|
+
# Set color values in new string intance
|
46
|
+
#
|
47
|
+
def set_color_parameters( params )
|
48
|
+
if (params.instance_of?(Hash))
|
49
|
+
@color = params[:color]
|
50
|
+
@background = params[:background]
|
51
|
+
@mode = params[:mode]
|
52
|
+
@uncolorized = params[:uncolorized]
|
53
|
+
self
|
54
|
+
else
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
public
|
60
|
+
|
61
|
+
#
|
62
|
+
# Change color of string
|
63
|
+
#
|
64
|
+
# Examples:
|
65
|
+
#
|
66
|
+
# puts "This is blue".colorize( :blue )
|
67
|
+
# puts "This is light blue".colorize( :light_blue )
|
68
|
+
# puts "This is also blue".colorize( :color => :blue )
|
69
|
+
# puts "This is light blue with red background".colorize( :color => :light_blue, :background => :red )
|
70
|
+
# puts "This is light blue with red background".colorize( :light_blue ).colorize( :background => :red )
|
71
|
+
# puts "This is blue text on red".blue.on_red
|
72
|
+
# puts "This is red on blue".colorize( :red ).on_blue
|
73
|
+
# puts "This is red on blue and underline".colorize( :red ).on_blue.underline
|
74
|
+
# puts "This is blue text on red".blue.on_red.blink
|
75
|
+
# puts "This is uncolorized".blue.on_red.uncolorize
|
76
|
+
#
|
77
|
+
def colorize( params )
|
78
|
+
return self unless STDOUT.isatty
|
79
|
+
|
80
|
+
begin
|
81
|
+
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/
|
82
|
+
rescue LoadError
|
83
|
+
raise 'You must gem install win32console to use colorize on Windows'
|
84
|
+
end
|
85
|
+
|
86
|
+
color_parameters = {}
|
87
|
+
|
88
|
+
if (params.instance_of?(Hash))
|
89
|
+
color_parameters[:color] = COLORS[params[:color]]
|
90
|
+
color_parameters[:background] = COLORS[params[:background]]
|
91
|
+
color_parameters[:mode] = MODES[params[:mode]]
|
92
|
+
elsif (params.instance_of?(Symbol))
|
93
|
+
color_parameters[:color] = COLORS[params]
|
94
|
+
end
|
95
|
+
|
96
|
+
color_parameters[:color] ||= @color ||= COLORS[:default]
|
97
|
+
color_parameters[:background] ||= @background ||= COLORS[:default]
|
98
|
+
color_parameters[:mode] ||= @mode ||= MODES[:default]
|
99
|
+
|
100
|
+
color_parameters[:uncolorized] ||= @uncolorized ||= self.dup
|
101
|
+
|
102
|
+
# calculate bright mode
|
103
|
+
color_parameters[:color] += 50 if color_parameters[:color] > 10
|
104
|
+
|
105
|
+
color_parameters[:background] += 50 if color_parameters[:background] > 10
|
106
|
+
|
107
|
+
"\033[#{color_parameters[:mode]};#{color_parameters[:color]+30};#{color_parameters[:background]+40}m#{color_parameters[:uncolorized]}\033[0m".set_color_parameters( color_parameters )
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Return uncolorized string
|
112
|
+
#
|
113
|
+
def uncolorize
|
114
|
+
@uncolorized || self
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Return true if sting is colorized
|
119
|
+
#
|
120
|
+
def colorized?
|
121
|
+
!defined?(@uncolorized).nil?
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Make some color and on_color methods
|
126
|
+
#
|
127
|
+
COLORS.each_key do | key |
|
128
|
+
next if key == :default
|
129
|
+
|
130
|
+
define_method key do
|
131
|
+
self.colorize( :color => key )
|
132
|
+
end
|
133
|
+
|
134
|
+
define_method "on_#{key}" do
|
135
|
+
self.colorize( :background => key )
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Methods for modes
|
141
|
+
#
|
142
|
+
MODES.each_key do | key |
|
143
|
+
next if key == :default
|
144
|
+
|
145
|
+
define_method key do
|
146
|
+
self.colorize( :mode => key )
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class << self
|
151
|
+
|
152
|
+
#
|
153
|
+
# Return array of available modes used by colorize method
|
154
|
+
#
|
155
|
+
def modes
|
156
|
+
keys = []
|
157
|
+
MODES.each_key do | key |
|
158
|
+
keys << key
|
159
|
+
end
|
160
|
+
keys
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# Return array of available colors used by colorize method
|
165
|
+
#
|
166
|
+
def colors
|
167
|
+
keys = []
|
168
|
+
COLORS.each_key do | key |
|
169
|
+
keys << key
|
170
|
+
end
|
171
|
+
keys
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# Display color matrix with color names.
|
176
|
+
#
|
177
|
+
def color_matrix( txt = "[X]" )
|
178
|
+
size = String.colors.length
|
179
|
+
String.colors.each do | color |
|
180
|
+
String.colors.each do | back |
|
181
|
+
print txt.colorize( :color => color, :background => back )
|
182
|
+
end
|
183
|
+
puts " < #{color}"
|
184
|
+
end
|
185
|
+
String.colors.reverse.each_with_index do | back, index |
|
186
|
+
puts "#{"|".rjust(txt.length)*(size-index)} < #{back}"
|
187
|
+
end
|
188
|
+
""
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
data/lib/rubysh/main.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "readline"
|
3
|
+
require 'yaml'
|
4
|
+
module RubySH
|
5
|
+
#
|
6
|
+
# The Shell class
|
7
|
+
#
|
8
|
+
class Shell
|
9
|
+
#
|
10
|
+
# Initializing some variables
|
11
|
+
#
|
12
|
+
def initialize
|
13
|
+
if File.exists?(".rsh")
|
14
|
+
@config = YAML.load_file(".rsh")
|
15
|
+
else
|
16
|
+
if File.exists?("#{ENV['HOME']}/.rsh")
|
17
|
+
@config = YAML.load_file("#{ENV['HOME']}/.rsh")
|
18
|
+
else
|
19
|
+
@config_file = Hash.new
|
20
|
+
@config_file['debug'] = false
|
21
|
+
@config_file = @config_file.to_yaml
|
22
|
+
File.open("#{ENV['HOME']}/.rsh", 'w') do |out|
|
23
|
+
out.write(@config_file)
|
24
|
+
end
|
25
|
+
@config = YAML.load_file("#{ENV['HOME']}/.rsh")
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
if @config['debug']
|
30
|
+
@debug = true
|
31
|
+
end
|
32
|
+
Screen.clear
|
33
|
+
trap('SIGINT') { exit unless @debug.nil? }
|
34
|
+
end
|
35
|
+
def prompt
|
36
|
+
puts "#{Time.now.strftime("%I:%M%p %m/%d/%Y")}".bright.cyan
|
37
|
+
loop {
|
38
|
+
# apparently colorize gem makes readlines glitch...
|
39
|
+
if ENV['rsh_ps1']
|
40
|
+
prompt = parse_prompt(ENV['rsh_ps1'])
|
41
|
+
else
|
42
|
+
prompt = "[#{current_dir?(true)}]% "
|
43
|
+
end
|
44
|
+
|
45
|
+
buf = Readline::readline(prompt, true)
|
46
|
+
enter(buf)
|
47
|
+
}
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def enter(data)
|
52
|
+
splitted_command = data.split(" ")
|
53
|
+
command = splitted_command[0]
|
54
|
+
splitted_command.shift
|
55
|
+
args = splitted_command.join(" ")
|
56
|
+
|
57
|
+
# hooking commands yay
|
58
|
+
if !command.nil?
|
59
|
+
case command
|
60
|
+
when 'cd'
|
61
|
+
begin
|
62
|
+
if args == "~"
|
63
|
+
Dir.chdir(ENV['HOME'])
|
64
|
+
else
|
65
|
+
Dir.chdir(args)
|
66
|
+
end
|
67
|
+
rescue Errno::ENOENT => e
|
68
|
+
puts "#{args}: Directory not found!".red
|
69
|
+
end
|
70
|
+
when 'export'
|
71
|
+
args = args.split('=')
|
72
|
+
ENV[args[0]] = args[1].gsub('"', '')
|
73
|
+
when 'quit'
|
74
|
+
exit
|
75
|
+
when 'help'
|
76
|
+
print_help
|
77
|
+
when 'about'
|
78
|
+
print_about
|
79
|
+
when 'eval'
|
80
|
+
eval_code(args)
|
81
|
+
else
|
82
|
+
if File.exists?("#{Dir.pwd}/#{command.gsub("./", "")}")
|
83
|
+
pid = fork {
|
84
|
+
exec "#{command} #{args}"
|
85
|
+
}
|
86
|
+
Process.wait pid
|
87
|
+
|
88
|
+
elsif command?(command)
|
89
|
+
puts "command: #{command}\nargs: #{args}" unless @debug.nil?
|
90
|
+
pid = fork {
|
91
|
+
exec "#{command} #{args}"
|
92
|
+
}
|
93
|
+
Process.wait pid
|
94
|
+
else
|
95
|
+
puts "rsh: '#{command}' not found".red
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
else
|
100
|
+
Readline::HISTORY.pop
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def command?(program)
|
106
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory|
|
107
|
+
File.executable?(File.join(directory, program.to_s))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def current_dir?(path_type)
|
112
|
+
path_type ? Dir.pwd.gsub(ENV['HOME'], '~') : Dir.pwd
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
def eval_code(args)
|
117
|
+
if args.nil?
|
118
|
+
puts "Usage: eval <ruby code>"
|
119
|
+
else
|
120
|
+
puts eval args
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def print_about
|
125
|
+
puts "RubySH (rsh)".red
|
126
|
+
puts "RubySH is a UNIX shell completely written using Ruby language.".light_red
|
127
|
+
puts "Built by Pablo Merino ☭\n"
|
128
|
+
end
|
129
|
+
|
130
|
+
def print_help
|
131
|
+
puts "RSH HELP".cyan.bright
|
132
|
+
puts "RSH is an integrated shell written in Ruby"
|
133
|
+
puts "You can use normal commands, execute scripts, and normal things, but you can also use the `eval \"ruby code\"' command to evaluate Ruby code"
|
134
|
+
end
|
135
|
+
|
136
|
+
def parse_prompt(prompt_str)
|
137
|
+
returner = prompt_str.gsub(/\/p/, current_dir?(true)).gsub(/\/u/, ENV['USER']).gsub(/\/t/, Time.now.strftime("%I:%M%p %m/%d/%Y"))
|
138
|
+
returner
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/lib/rubysh/utils.rb
ADDED
data/rubysh.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'RubySH'
|
3
|
+
s.version = '1.0'
|
4
|
+
s.summary = 'RSH is a SH compliant shell, completely coded in Ruby'
|
5
|
+
s.description = 'RSH is a UNIX and SH compliant shell built in Ruby. It features all the traditional Shell commands (basically anything in the $PATH)'
|
6
|
+
|
7
|
+
s.authors = ['Pablo Merino']
|
8
|
+
s.email = ['pablo.perso1995@gmail.com']
|
9
|
+
s.homepage = 'https://github.com/pablo-merino/rsh'
|
10
|
+
|
11
|
+
s.files = Dir['./**/*']
|
12
|
+
|
13
|
+
# Supress the warning about no rubyforge project
|
14
|
+
s.rubyforge_project = 'nowarning'
|
15
|
+
s.executables = `ls bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: RubySH
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pablo Merino
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-07 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: RSH is a UNIX and SH compliant shell built in Ruby. It features all the
|
15
|
+
traditional Shell commands (basically anything in the $PATH)
|
16
|
+
email:
|
17
|
+
- pablo.perso1995@gmail.com
|
18
|
+
executables:
|
19
|
+
- rsh
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- ./bin/rsh
|
24
|
+
- ./lib/rubysh/colorize.rb
|
25
|
+
- ./lib/rubysh/main.rb
|
26
|
+
- ./lib/rubysh/utils.rb
|
27
|
+
- ./lib/rubysh.rb
|
28
|
+
- ./RubySH-1.0.gem
|
29
|
+
- ./rubysh.gemspec
|
30
|
+
- !binary |-
|
31
|
+
YmluL3JzaA==
|
32
|
+
homepage: https://github.com/pablo-merino/rsh
|
33
|
+
licenses: []
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project: nowarning
|
52
|
+
rubygems_version: 1.8.21
|
53
|
+
signing_key:
|
54
|
+
specification_version: 3
|
55
|
+
summary: RSH is a SH compliant shell, completely coded in Ruby
|
56
|
+
test_files: []
|