chitin 1.0.1 → 1.0.2
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/ANNOUNCEMENT +40 -34
- data/TODO +7 -18
- data/chitin.gemspec +1 -1
- data/lib/chitin/commands/builtins.rb +1 -11
- data/lib/chitin/commands/executable.rb +6 -0
- data/lib/chitin/commands/pipe.rb +1 -5
- data/lib/chitin/commands/ruby.rb +77 -65
- data/lib/chitin/commands/runnable.rb +23 -1
- data/lib/chitin/core_ext/class.rb +9 -0
- data/lib/chitin/core_ext/coolline.rb +2 -1
- data/lib/chitin/file.rb +55 -65
- data/lib/chitin/session.rb +41 -27
- data/lib/chitin/version.rb +1 -1
- metadata +5 -4
data/ANNOUNCEMENT
CHANGED
@@ -3,58 +3,64 @@ chitin
|
|
3
3
|
by Ari Brown
|
4
4
|
http://bitbucket.org/seydar/chitin
|
5
5
|
|
6
|
-
|
6
|
+
% gem install chitin # for bash
|
7
7
|
|
8
|
-
|
9
|
-
at least it's bash-esque. There are a few hipsters among us who are using fish
|
10
|
-
or zsh or whatever. A few of the older persuasion are into csh and tcsh.
|
11
|
-
But that's not the point. The point is you're on a Ruby mailing list but you're
|
12
|
-
not using a Ruby shell. It's time to upgrade. It's time to upgrade your shell
|
13
|
-
to Chitin. I hope you all get the joke. I made it myself. The joke and the shell.
|
8
|
+
Hai everybahdy
|
14
9
|
|
15
10
|
== So what IS Chitin?
|
16
11
|
|
17
12
|
* Chitin is a Ruby interpreter
|
18
13
|
* Turned into a shell.
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
15
|
+
I hope you all get the joke. I made it myself. The joke and the shell.
|
16
|
+
|
17
|
+
Everything you type is Ruby -- remember that. So let's look at it in action.
|
18
|
+
Remember that the tab completion makes typing quotes painless. Plus you don't
|
19
|
+
even need closing quotes if they're the final character in a line:
|
20
|
+
|
21
|
+
% hg.commit :m => 'fixed issues with procs in pipes...
|
22
|
+
% hg.push
|
23
|
+
pushing to https://seydar:***@bitbucket.org/seydar/chitin
|
24
|
+
...
|
25
|
+
remote: bb/acl: seydar is allowed. accepted payload.
|
26
|
+
% cat("ANNOUNCEMENT") | pbcopy
|
27
|
+
% ll
|
28
|
+
total 136
|
29
|
+
-rw-r--r-- 1 ari staff 1.7K Nov 25 14:43 ANNOUNCEMENT
|
30
|
+
...
|
31
|
+
-rw-r--r-- 1 ari staff 7.7K Nov 24 20:44 sample.txt
|
32
|
+
% rm "chitin-1.0.1.gem"
|
33
|
+
% gem.build "chitin.gemspec"
|
34
|
+
Successfully built RubyGem
|
35
|
+
Name: chitin
|
36
|
+
Version: 1.0.1
|
37
|
+
File: chitin-1.0.1.gem
|
38
|
+
% vim "ANNOUNCEMENT"
|
39
|
+
% ll | grep('gem')
|
40
|
+
-rw-r--r-- 1 ari staff 24K Nov 25 14:49 chitin-1.0.1.gem
|
41
|
+
-rw-r--r-- 1 ari staff 883B Nov 21 14:43 chitin.gemspec
|
42
|
+
% ll | split("\n").map {|l| l.size }
|
43
|
+
=> [9, 57, 51, 49, 48, 61, 59, 53, 48, 55]
|
40
44
|
|
41
45
|
== Why use it?
|
42
46
|
|
43
47
|
Because it's written in Ruby and supadupes easy to modify. Also:
|
44
48
|
|
45
|
-
* No need to use closing quotes. If you need a final quote in a line, don't
|
46
|
-
sweat it. Chitin will take care of that.
|
47
|
-
* Syntax highlighting while you type (thanks to Coolline!)
|
48
|
-
* You can do simple arithmatic on the command line without having to switch
|
49
|
-
interfaces (this was the original itch I had to scratch).
|
50
49
|
* The power of Ruby in a shell
|
51
50
|
* The command utility of a shell in Ruby
|
52
|
-
*
|
51
|
+
* Text processing is SO. MUCH. EASIER.
|
53
52
|
* A much more programmatic shell
|
54
53
|
* Prevents against accidental `rm -rf /usr /local/bin` like that one thing
|
55
54
|
we all saw on Reddit.
|
55
|
+
* Syntax highlighting while you type (thanks to Coolline!)
|
56
|
+
* You can do simple arithmetic on the command line without having to switch
|
57
|
+
interfaces (this was the original itch I had to scratch).
|
58
|
+
* No underlying shell usage
|
59
|
+
* Sweet tab completion
|
60
|
+
* No need to use closing quotes. If you need a final quote in a line, don't
|
61
|
+
sweat it. Chitin will take care of that.
|
62
|
+
* You can set key bindings to arbitrary keys
|
56
63
|
* Makes for a great Christmas present
|
57
|
-
* Text processing is SO. MUCH. EASIER.
|
58
64
|
* Great library for calling executable files from your own program without
|
59
65
|
shelling your soul or shelling out.
|
60
66
|
|
data/TODO
CHANGED
@@ -1,32 +1,21 @@
|
|
1
1
|
FUTURE:
|
2
|
-
* add STDERR support
|
3
|
-
* fix it so that self.err isn't alone in the whole `if self.err` bit.
|
4
2
|
* set local variables in config, have them appear in shell
|
5
3
|
* getting the menu to NOT have leading quotes
|
6
4
|
* remove/edit history
|
7
5
|
-> important for removing passwords if accidentally typed
|
8
6
|
* improve library usage of executables
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
|
8
|
+
QUIRKS:
|
9
|
+
* menu doesn't erase itself sometimes
|
10
|
+
-> cat and tabcomplete a file that is empty. output is correct but confusing
|
13
11
|
|
14
12
|
FAILURES:
|
15
|
-
* cursor display issues with the menu
|
16
|
-
-> it places the cursor at the location of the cursor on the input line
|
17
|
-
except the cursor is actually placed on the final line of the menu
|
18
|
-
(the input line is several lines above it)
|
19
|
-
* get coolline to play well with missing newlines before it
|
20
|
-
-> right now it preserves junk on the line up until the first character is
|
21
|
-
typed. once the user types something, the line is made pristine.
|
22
|
-
-> see if you can replace reset_line with something like
|
23
|
-
reset_what_was_written, deleting the prompt and the visible portion of
|
24
|
-
the line
|
25
13
|
|
26
14
|
Questions:
|
27
15
|
* Why do you have to do @line = '' in Coolline in order to not affect the
|
28
16
|
history? History calls el.dup which creates a new object. It shouldn't
|
29
17
|
matter if I do @line.clear on the original.
|
30
|
-
|
31
|
-
|
18
|
+
|
19
|
+
RELEASE
|
20
|
+
* failures
|
32
21
|
|
data/chitin.gemspec
CHANGED
@@ -25,7 +25,7 @@ DESC
|
|
25
25
|
# specify any dependencies here; for example:
|
26
26
|
# s.add_development_dependency "rspec"
|
27
27
|
s.add_runtime_dependency "wirble"
|
28
|
-
s.add_runtime_dependency "coolline"
|
28
|
+
s.add_runtime_dependency "coolline", ">= 0.4.0"
|
29
29
|
s.add_runtime_dependency "coderay"
|
30
30
|
end
|
31
31
|
|
@@ -96,18 +96,8 @@ module Chitin
|
|
96
96
|
module Prompts
|
97
97
|
# The standard prompt. Must return a string. Override this to provide
|
98
98
|
# a custom prompt.
|
99
|
-
def big_prompt
|
100
|
-
"+-#{'-' * ENV['USER'].length}--#{'-' * short_pwd.length}-+\n" +
|
101
|
-
"| #{ENV['USER']}: #{short_pwd} |\n" +
|
102
|
-
"+-#{'-' * ENV['USER'].length}--#{'-' * short_pwd.length}-+ "
|
103
|
-
end
|
104
|
-
|
105
|
-
def small_prompt
|
106
|
-
"#{ENV['USER']}: #{short_pwd} % "
|
107
|
-
end
|
108
|
-
|
109
99
|
def prompt
|
110
|
-
|
100
|
+
"#{ENV['USER']}: #{short_pwd} % "
|
111
101
|
end
|
112
102
|
end
|
113
103
|
include Prompts
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Chitin
|
2
2
|
class Executable
|
3
|
+
__sweep__ :[]
|
4
|
+
|
3
5
|
include Runnable
|
4
6
|
|
5
7
|
def initialize(path, *args)
|
@@ -54,6 +56,10 @@ module Chitin
|
|
54
56
|
@args += arr.map {|a| a.to_s }
|
55
57
|
self # need to return this so that the shell can just run it
|
56
58
|
end
|
59
|
+
|
60
|
+
def returning
|
61
|
+
:io
|
62
|
+
end
|
57
63
|
|
58
64
|
# TODO fix it so that self.err isn't alone in the whole `if self.err`
|
59
65
|
# bit. figure out a good way to make it default or something. i dunno.
|
data/lib/chitin/commands/pipe.rb
CHANGED
data/lib/chitin/commands/ruby.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Chitin
|
2
2
|
class StringMethod
|
3
|
+
__sweep__ :[]
|
4
|
+
|
3
5
|
include Runnable
|
4
6
|
|
5
7
|
attr_reader :chains
|
@@ -18,6 +20,7 @@ module Chitin
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def method_missing(*arr, &block)
|
23
|
+
puts caller[0]
|
21
24
|
latest = [*arr]
|
22
25
|
latest << block if block
|
23
26
|
@chains << latest
|
@@ -29,7 +32,7 @@ module Chitin
|
|
29
32
|
def result
|
30
33
|
val = self[:in].read
|
31
34
|
@chains.each do |arr|
|
32
|
-
val = if arr.last
|
35
|
+
val = if Proc === arr.last
|
33
36
|
val.send *arr[0..-2], &arr[-1]
|
34
37
|
else
|
35
38
|
val.send *arr
|
@@ -53,6 +56,8 @@ module Chitin
|
|
53
56
|
reset
|
54
57
|
|
55
58
|
@pid = child
|
59
|
+
|
60
|
+
self
|
56
61
|
end
|
57
62
|
|
58
63
|
# like #run, except instead of writing the output
|
@@ -67,13 +72,18 @@ module Chitin
|
|
67
72
|
end
|
68
73
|
|
69
74
|
def wait
|
70
|
-
Process.wait
|
75
|
+
@pid && Process.wait(@pid)
|
71
76
|
end
|
72
77
|
|
73
78
|
def reset
|
74
79
|
self.in, self.out, self.err = nil
|
75
80
|
end
|
81
|
+
|
82
|
+
def returning
|
83
|
+
:ruby
|
84
|
+
end
|
76
85
|
|
86
|
+
# fix this. What if someone passes an executable as an argument?
|
77
87
|
def to_s
|
78
88
|
@chains.map do |arr|
|
79
89
|
"#{arr[0]}(#{arr[1..-1].map {|a| a.is_a?(Proc) ? "&block" : a.inspect }.join ', '})"
|
@@ -86,67 +96,69 @@ module Chitin
|
|
86
96
|
end
|
87
97
|
end
|
88
98
|
|
89
|
-
class Proc
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
99
|
+
# class Proc
|
100
|
+
# # So let's quick chat about what including Runnable to a proc means.
|
101
|
+
# # It means that it can be chained with pipes.
|
102
|
+
# # It also means that you can run private methods with #[].
|
103
|
+
# # The important thing isn't that you can run private methods. You could
|
104
|
+
# # do that since the beginning of time.
|
105
|
+
# # The take-away is that it OVERRIDES #[]. In the words of Joe Biden,
|
106
|
+
# # this is a big fucking deal.
|
107
|
+
# #
|
108
|
+
# # whatdo.jpg
|
109
|
+
# #
|
110
|
+
# # This means that you cannot, in the environment of Chitin, use
|
111
|
+
# # Proc#[] for anything other than accessing private methods. This
|
112
|
+
# # means it does not play well with others. This is what we in the biz
|
113
|
+
# # call bad.
|
114
|
+
# #
|
115
|
+
# # Maybe I shouldn't even offer this as a feature.
|
116
|
+
# undef_method :[]
|
117
|
+
# include Chitin::Runnable
|
118
|
+
#
|
119
|
+
# # # access private methods
|
120
|
+
# # def [](*args)
|
121
|
+
# # if method(args.first)
|
122
|
+
# # method(args.first).call *args[1..-1]
|
123
|
+
# # else
|
124
|
+
# # raise NoMethodError.new("undefined method" +
|
125
|
+
# # "`#{args.first}' for #{self}:#{self.class}")
|
126
|
+
# # end
|
127
|
+
# # end
|
128
|
+
#
|
129
|
+
# def |(other)
|
130
|
+
# Pipe.new self, other
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# private
|
134
|
+
#
|
135
|
+
# def run
|
136
|
+
# child = fork do
|
137
|
+
# self.out.puts call(self.in)
|
138
|
+
#
|
139
|
+
# close_all
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# close_all
|
143
|
+
# reset
|
144
|
+
#
|
145
|
+
# @pid = child
|
146
|
+
# end
|
147
|
+
#
|
148
|
+
# def raw_run
|
149
|
+
# val = call self.in
|
150
|
+
#
|
151
|
+
# close_all
|
152
|
+
# reset
|
153
|
+
# val
|
154
|
+
# end
|
155
|
+
#
|
156
|
+
# def wait
|
157
|
+
# Process.wait @pid
|
158
|
+
# end
|
159
|
+
#
|
160
|
+
# def reset
|
161
|
+
# self.in, self.out, self.err = nil
|
162
|
+
# end
|
163
|
+
# end
|
152
164
|
|
@@ -15,7 +15,22 @@ module Chitin
|
|
15
15
|
|
16
16
|
self
|
17
17
|
end
|
18
|
+
|
19
|
+
def >>(io)
|
20
|
+
case io
|
21
|
+
when IO, File
|
22
|
+
self[:set_err, io]
|
23
|
+
when String, FileObject
|
24
|
+
f = File.open io, 'w'
|
25
|
+
self[:set_err, f]
|
26
|
+
f.close
|
27
|
+
else
|
28
|
+
raise "Unknown piping type: #{io.class}"
|
29
|
+
end
|
18
30
|
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
19
34
|
# access private methods
|
20
35
|
def [](*args)
|
21
36
|
if method(args.first)
|
@@ -25,13 +40,20 @@ module Chitin
|
|
25
40
|
"`#{args.first}' for #{self}:#{self.class}")
|
26
41
|
end
|
27
42
|
end
|
28
|
-
|
43
|
+
|
44
|
+
def bg!; @bg = true; self; end
|
45
|
+
def bg?; @bg; end
|
46
|
+
|
29
47
|
private
|
30
48
|
|
31
49
|
attr_accessor :bg
|
32
50
|
attr_accessor :in
|
33
51
|
attr_accessor :out
|
34
52
|
attr_accessor :err
|
53
|
+
|
54
|
+
def returning
|
55
|
+
raise "Not Yet Implemented"
|
56
|
+
end
|
35
57
|
|
36
58
|
# Generally the same as +run+, except for the ruby commands
|
37
59
|
# they return real ruby that can be given back to the user.
|
data/lib/chitin/file.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module Chitin
|
2
2
|
class FSObject
|
3
|
+
include Enumerable
|
4
|
+
|
3
5
|
attr_accessor :path
|
6
|
+
attr_accessor :search
|
4
7
|
|
5
8
|
# The choice to not have File.expand_path here is explicitly done.
|
6
9
|
# Relativity is up to the user.
|
@@ -8,6 +11,7 @@ module Chitin
|
|
8
11
|
# and over again on lists of files.
|
9
12
|
def initialize(path, opts={})
|
10
13
|
@path = path
|
14
|
+
@search = proc { path }
|
11
15
|
@unknown = opts[:unknown]
|
12
16
|
end
|
13
17
|
|
@@ -15,6 +19,37 @@ module Chitin
|
|
15
19
|
@unknown
|
16
20
|
end
|
17
21
|
|
22
|
+
def files
|
23
|
+
return @files if @files
|
24
|
+
files = Dir[search.call]
|
25
|
+
@files = files.inject({}) do |h, f|
|
26
|
+
f = f[2..-1] if f.start_with? './'
|
27
|
+
h[f] = if File.directory? f
|
28
|
+
D f
|
29
|
+
elsif File.file? f
|
30
|
+
F f
|
31
|
+
elsif File.symlink? f
|
32
|
+
S f
|
33
|
+
else
|
34
|
+
FSObject.new f, :unknown => true
|
35
|
+
end
|
36
|
+
|
37
|
+
h
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def each(&block)
|
42
|
+
files.values.each &block
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_a
|
46
|
+
files.values
|
47
|
+
end
|
48
|
+
|
49
|
+
def size
|
50
|
+
files.size
|
51
|
+
end
|
52
|
+
|
18
53
|
def lstat
|
19
54
|
File.lstat @path
|
20
55
|
end
|
@@ -42,7 +77,7 @@ module Chitin
|
|
42
77
|
block.call f
|
43
78
|
end
|
44
79
|
end
|
45
|
-
|
80
|
+
|
46
81
|
def delete
|
47
82
|
File.safe_unlink @path
|
48
83
|
end
|
@@ -71,49 +106,27 @@ module Chitin
|
|
71
106
|
end
|
72
107
|
|
73
108
|
class Directory < FSObject
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
return @files if @files
|
78
|
-
files = Dir[File.join(path, '*')]
|
79
|
-
@files = files.inject({}) do |h, f|
|
80
|
-
f = f[2..-1] if f.start_with? './'
|
81
|
-
h[f] = if File.directory? f
|
82
|
-
D f
|
83
|
-
elsif File.file? f
|
84
|
-
F f
|
85
|
-
elsif File.symlink? f
|
86
|
-
S f
|
87
|
-
else
|
88
|
-
FSObject.new f, :unknown => true
|
89
|
-
end
|
90
|
-
|
91
|
-
h
|
92
|
-
end
|
109
|
+
def initialize(path, opts={})
|
110
|
+
super
|
111
|
+
@search = proc { File.join self.path, '*' }
|
93
112
|
end
|
94
|
-
|
113
|
+
|
95
114
|
def down
|
96
|
-
|
115
|
+
@path = File.join path, '**'
|
116
|
+
@files = nil
|
97
117
|
self
|
98
118
|
end
|
99
119
|
|
100
120
|
# Get a specific level down
|
101
121
|
def level(n=1)
|
102
|
-
n.times {
|
122
|
+
n.times { @path = File.join self.path, '*' }
|
123
|
+
@files = nil
|
103
124
|
self
|
104
125
|
end
|
105
|
-
|
106
|
-
def each(&block)
|
107
|
-
files.values.each &block
|
108
|
-
end
|
109
|
-
|
110
|
-
def to_a
|
111
|
-
files.values
|
112
|
-
end
|
113
|
-
|
126
|
+
|
114
127
|
def delete
|
115
128
|
# this is probably unwise...
|
116
|
-
File.rm_rf
|
129
|
+
File.rm_rf path
|
117
130
|
end
|
118
131
|
|
119
132
|
def inspect
|
@@ -124,40 +137,17 @@ module Chitin
|
|
124
137
|
false
|
125
138
|
end
|
126
139
|
end
|
140
|
+
end
|
127
141
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
class Abyss
|
133
|
-
def eof?
|
134
|
-
true
|
135
|
-
end
|
136
|
-
|
137
|
-
def read
|
138
|
-
""
|
139
|
-
end
|
140
|
-
alias_method :readline, :read
|
141
|
-
|
142
|
-
def <<(*args)
|
143
|
-
end
|
144
|
-
alias_method :write, :<<
|
145
|
-
alias_method :puts, :<<
|
142
|
+
module Kernel
|
143
|
+
def D(path); Chitin::Directory.new path; end
|
144
|
+
def F(path); Chitin::FileObject.new path; end
|
145
|
+
def S(path); Chitin::Symlink.new path; end
|
146
146
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
147
|
+
alias_method :d, :D
|
148
|
+
alias_method :f, :F
|
149
|
+
alias_method :s, :S
|
151
150
|
|
152
|
-
|
153
|
-
true
|
154
|
-
end
|
155
|
-
end
|
151
|
+
NULLIN = NULLOUT = NULLERR = File.open File::NULL
|
156
152
|
end
|
157
|
-
|
158
|
-
def D(path); Chitin::Directory.new path; end
|
159
|
-
def F(path); Chitin::FileObject.new path; end
|
160
|
-
def S(path); Chitin::Symlink.new path; end
|
161
|
-
|
162
|
-
NULLIN = NULLOUT = NULLERR = Chitin::Abyss.new
|
163
153
|
|
data/lib/chitin/session.rb
CHANGED
@@ -80,6 +80,20 @@ module Chitin
|
|
80
80
|
# THIS METHOD WILL POSSIBLY RETURN NIL!!!!!
|
81
81
|
# So it can return a string or nil. Remember that, folks.
|
82
82
|
def read
|
83
|
+
# find out the column (1-indexed) that will next be printed
|
84
|
+
# if it's NOT 1, then something was printed, and we want to insert
|
85
|
+
# a newline
|
86
|
+
a = nil
|
87
|
+
STDIN.raw do
|
88
|
+
print "\e[6n"
|
89
|
+
a = STDIN.gets 'R'
|
90
|
+
end
|
91
|
+
|
92
|
+
if a.chomp('R').split(';').last != '1'
|
93
|
+
puts
|
94
|
+
puts "(no trailing newline)"
|
95
|
+
end
|
96
|
+
|
83
97
|
inp = @editor.readline @sandbox.prompt
|
84
98
|
|
85
99
|
|
@@ -97,21 +111,32 @@ module Chitin
|
|
97
111
|
@sandbox.evaluate val
|
98
112
|
end
|
99
113
|
|
100
|
-
def
|
101
|
-
|
114
|
+
def returning_ruby?(res)
|
115
|
+
# We have to use #stat here because reopened pipes retain the file
|
116
|
+
# descriptor of the original pipe. Example:
|
117
|
+
# r, w = IO.pipe; r.reopen STDIN; r == STDIN # => false
|
118
|
+
# Thus, we have to use #stat (or, more lamely, #inspect).
|
119
|
+
return true unless Runnable === res
|
120
|
+
|
121
|
+
res[:returning] == :ruby &&
|
122
|
+
(res[:out] == nil ||
|
123
|
+
res[:out].stat == STDOUT.stat)
|
124
|
+
end
|
125
|
+
|
126
|
+
def all_not_ruby?(res)
|
127
|
+
if Array === res
|
128
|
+
!res.empty? && res.map {|r| not returning_ruby? r }.all?
|
129
|
+
else
|
130
|
+
not returning_ruby? res
|
131
|
+
end
|
102
132
|
end
|
103
133
|
|
104
134
|
def display(res)
|
105
135
|
# The reason that this is here instead of in #evaluate is that
|
106
136
|
# pipes could, in fact, have NO display output, but that isn't for
|
107
137
|
# #evaluate to decide; rather, it is for #display
|
108
|
-
|
109
|
-
|
110
|
-
# chained, and proc is also a general Ruby type, so we don't want to
|
111
|
-
# automatically call it.
|
112
|
-
if shell_command?(res) || (res.is_a?(Array) && !res.empty? && res.map {|r| shell_command? r }.all?)
|
113
|
-
|
114
|
-
res = [res] unless res.is_a?(Array)
|
138
|
+
if all_not_ruby? res
|
139
|
+
res = [res] unless Array === res
|
115
140
|
|
116
141
|
res.each do |res|
|
117
142
|
# set up the inputs and outputs
|
@@ -125,30 +150,19 @@ module Chitin
|
|
125
150
|
|
126
151
|
else # else it's a standard ruby type (or a pipe returning as such)
|
127
152
|
|
128
|
-
|
129
|
-
# RUBY values pass through here
|
130
|
-
txt = @config.post_processing[:color].call res.inspect
|
131
|
-
puts " => #{txt}"
|
132
|
-
else
|
153
|
+
if Pipe === res || StringMethod === res
|
133
154
|
# set up the inputs and outputs
|
134
155
|
res[:set_in, STDIN] unless res[:in]
|
135
156
|
res[:set_out, STDOUT] unless res[:out]
|
136
157
|
res[:set_err, STDOUT] unless res[:err]
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
# Thus, we have to use #stat (or, more lamely, #inspect).
|
142
|
-
if res[:out].stat == STDOUT.stat
|
143
|
-
val = res[:raw_run]
|
144
|
-
txt = @config.post_processing[:color].call val.inspect
|
145
|
-
puts " => #{txt}"
|
146
|
-
else
|
147
|
-
res[:run]
|
148
|
-
res[:wait] unless res[:bg]
|
149
|
-
end
|
158
|
+
|
159
|
+
val = res[:raw_run]
|
160
|
+
else
|
161
|
+
val = res
|
150
162
|
end
|
151
163
|
|
164
|
+
txt = @config.post_processing[:color].call val.inspect
|
165
|
+
puts " => #{txt}"
|
152
166
|
end
|
153
167
|
|
154
168
|
# Run all the post_processing stuff
|
data/lib/chitin/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chitin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: wirble
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 0.4.0
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 0.4.0
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: coderay
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,6 +84,7 @@ files:
|
|
84
84
|
- lib/chitin/commands/pipe.rb
|
85
85
|
- lib/chitin/commands/ruby.rb
|
86
86
|
- lib/chitin/commands/runnable.rb
|
87
|
+
- lib/chitin/core_ext/class.rb
|
87
88
|
- lib/chitin/core_ext/coolline.rb
|
88
89
|
- lib/chitin/core_ext/io.rb
|
89
90
|
- lib/chitin/core_ext/object.rb
|