clone 1.0.0.alpha → 1.0.0.beta
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/Gemfile +1 -0
- data/LICENSE.txt +22 -0
- data/README.md +22 -1
- data/VERSION +1 -1
- data/bin/clone +7 -0
- data/clone.gemspec +4 -0
- data/docs/readme +16 -0
- data/docs/readme.txt +5 -0
- data/lib/clone.rb +13 -2
- data/lib/clone/config/config.rb +19 -0
- data/lib/clone/config/config.yml +22 -0
- data/lib/clone/config/default_config.yml +20 -0
- data/lib/clone/config/require.rb +3 -0
- data/lib/clone/config/version.rb +10 -0
- data/lib/clone/config/yml.rb +22 -0
- data/lib/clone/config/z_defaults.rb +28 -0
- data/lib/clone/generator/engine.rb +581 -0
- data/lib/clone/generator/terminal.rb +104 -0
- data/lib/clone/helpers/helper_methods.rb +251 -0
- data/lib/clone/helpers/local_methods.rb +150 -0
- data/lib/clone/helpers/require.rb +37 -0
- data/module/Marshal.4.8 +0 -0
- data/module/Marshal.4.8.Z +0 -0
- data/module/gems/commander-4.1.3/.gitignore +6 -0
- data/module/gems/commander-4.1.3/.travis.yml +11 -0
- data/module/gems/commander-4.1.3/DEVELOPMENT +15 -0
- data/module/gems/commander-4.1.3/Gemfile +3 -0
- data/module/gems/commander-4.1.3/History.rdoc +345 -0
- data/module/gems/commander-4.1.3/Manifest +38 -0
- data/module/gems/commander-4.1.3/README.rdoc +375 -0
- data/module/gems/commander-4.1.3/Rakefile +10 -0
- data/module/gems/commander-4.1.3/bin/commander +55 -0
- data/module/gems/commander-4.1.3/commander.gemspec +26 -0
- data/module/gems/commander-4.1.3/lib/commander.rb +32 -0
- data/module/gems/commander-4.1.3/lib/commander/blank.rb +8 -0
- data/module/gems/commander-4.1.3/lib/commander/command.rb +213 -0
- data/module/gems/commander-4.1.3/lib/commander/core_ext.rb +3 -0
- data/module/gems/commander-4.1.3/lib/commander/core_ext/array.rb +26 -0
- data/module/gems/commander-4.1.3/lib/commander/core_ext/object.rb +11 -0
- data/module/gems/commander-4.1.3/lib/commander/delegates.rb +13 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters.rb +8 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters/base.rb +18 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters/terminal.rb +20 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters/terminal/command_help.erb +35 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters/terminal/help.erb +36 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters/terminal_compact.rb +12 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters/terminal_compact/command_help.erb +27 -0
- data/module/gems/commander-4.1.3/lib/commander/help_formatters/terminal_compact/help.erb +29 -0
- data/module/gems/commander-4.1.3/lib/commander/import.rb +10 -0
- data/module/gems/commander-4.1.3/lib/commander/platform.rb +8 -0
- data/module/gems/commander-4.1.3/lib/commander/runner.rb +411 -0
- data/module/gems/commander-4.1.3/lib/commander/user_interaction.rb +521 -0
- data/module/gems/commander-4.1.3/lib/commander/version.rb +3 -0
- data/module/gems/commander-4.1.3/spec/command_spec.rb +157 -0
- data/module/gems/commander-4.1.3/spec/core_ext/array_spec.rb +20 -0
- data/module/gems/commander-4.1.3/spec/core_ext/object_spec.rb +21 -0
- data/module/gems/commander-4.1.3/spec/help_formatters/terminal_spec.rb +67 -0
- data/module/gems/commander-4.1.3/spec/runner_spec.rb +526 -0
- data/module/gems/commander-4.1.3/spec/spec_helper.rb +59 -0
- data/module/gems/commander-4.1.3/spec/ui_spec.rb +30 -0
- data/module/gems/hello.rb +1 -0
- data/module/gems/highline-1.6.19/.gitignore +2 -0
- data/module/gems/highline-1.6.19/AUTHORS +3 -0
- data/module/gems/highline-1.6.19/CHANGELOG +346 -0
- data/module/gems/highline-1.6.19/COPYING +340 -0
- data/module/gems/highline-1.6.19/INSTALL +55 -0
- data/module/gems/highline-1.6.19/LICENSE +7 -0
- data/module/gems/highline-1.6.19/README.rdoc +63 -0
- data/module/gems/highline-1.6.19/Rakefile +50 -0
- data/module/gems/highline-1.6.19/TODO +6 -0
- data/module/gems/highline-1.6.19/examples/ansi_colors.rb +38 -0
- data/module/gems/highline-1.6.19/examples/asking_for_arrays.rb +18 -0
- data/module/gems/highline-1.6.19/examples/basic_usage.rb +75 -0
- data/module/gems/highline-1.6.19/examples/color_scheme.rb +32 -0
- data/module/gems/highline-1.6.19/examples/get_character.rb +12 -0
- data/module/gems/highline-1.6.19/examples/limit.rb +12 -0
- data/module/gems/highline-1.6.19/examples/menus.rb +65 -0
- data/module/gems/highline-1.6.19/examples/overwrite.rb +19 -0
- data/module/gems/highline-1.6.19/examples/page_and_wrap.rb +322 -0
- data/module/gems/highline-1.6.19/examples/password.rb +7 -0
- data/module/gems/highline-1.6.19/examples/repeat_entry.rb +21 -0
- data/module/gems/highline-1.6.19/examples/trapping_eof.rb +22 -0
- data/module/gems/highline-1.6.19/examples/using_readline.rb +17 -0
- data/module/gems/highline-1.6.19/highline.gemspec +37 -0
- data/module/gems/highline-1.6.19/lib/highline.rb +1012 -0
- data/module/gems/highline-1.6.19/lib/highline/color_scheme.rb +134 -0
- data/module/gems/highline-1.6.19/lib/highline/compatibility.rb +16 -0
- data/module/gems/highline-1.6.19/lib/highline/import.rb +41 -0
- data/module/gems/highline-1.6.19/lib/highline/menu.rb +398 -0
- data/module/gems/highline-1.6.19/lib/highline/question.rb +475 -0
- data/module/gems/highline-1.6.19/lib/highline/simulate.rb +48 -0
- data/module/gems/highline-1.6.19/lib/highline/string_extensions.rb +131 -0
- data/module/gems/highline-1.6.19/lib/highline/style.rb +181 -0
- data/module/gems/highline-1.6.19/lib/highline/system_extensions.rb +222 -0
- data/module/gems/highline-1.6.19/setup.rb +1360 -0
- data/module/gems/highline-1.6.19/site/.cvsignore +1 -0
- data/module/gems/highline-1.6.19/site/highline.css +65 -0
- data/module/gems/highline-1.6.19/site/images/logo.png +0 -0
- data/module/gems/highline-1.6.19/site/index.html +58 -0
- data/module/gems/highline-1.6.19/test/string_methods.rb +32 -0
- data/module/gems/highline-1.6.19/test/tc_color_scheme.rb +96 -0
- data/module/gems/highline-1.6.19/test/tc_highline.rb +1128 -0
- data/module/gems/highline-1.6.19/test/tc_import.rb +52 -0
- data/module/gems/highline-1.6.19/test/tc_menu.rb +439 -0
- data/module/gems/highline-1.6.19/test/tc_string_extension.rb +20 -0
- data/module/gems/highline-1.6.19/test/tc_string_highline.rb +38 -0
- data/module/gems/highline-1.6.19/test/tc_style.rb +567 -0
- data/module/gems/highline-1.6.19/test/ts_all.rb +16 -0
- data/module/latest_specs.4.8 +0 -0
- data/module/latest_specs.4.8.gz +0 -0
- data/module/prerelease_specs.4.8 +0 -0
- data/module/prerelease_specs.4.8.gz +0 -0
- data/module/specs.4.8 +0 -0
- data/module/specs.4.8.gz +0 -0
- data/samples/blather/restlike/Gemfile +4 -0
- data/samples/blather/restlike/cmd.yml +1 -0
- data/samples/blather/restlike/lib/blather.rb +9 -0
- data/samples/blather/restlike/lib/blather/dsl/api.rb +78 -0
- data/samples/blather/restlike/lib/blather/dsl/call.rb +13 -0
- data/samples/blather/restlike/lib/blather/dsl/client.rb +58 -0
- data/samples/blather/restlike/lib/blather/dsl/config.rb +11 -0
- data/samples/blather/restlike/lib/blather/dsl/extraDSL.rb +163 -0
- data/samples/blather/restlike/lib/blather/meta/require.rb +8 -0
- data/samples/blather/restlike/lib/blather/meta/xmpp.yml +5 -0
- data/samples/blather/restlike/lib/blather/vendors/xmpp_default.rb +27 -0
- data/samples/blather/restlike/readme +2 -0
- data/samples/grape/init/Gemfile +2 -0
- data/samples/grape/init/cmd.yml +3 -0
- data/samples/grape/init/config.ru +2 -0
- data/samples/grape/init/docs/grape/documentation.txt +939 -0
- data/samples/grape/init/docs/grape/generate_rest_routes.rb +37 -0
- data/samples/grape/init/docs/grape/ls_routes.rb +31 -0
- data/samples/grape/init/lib/grape.rb +4 -0
- data/samples/grape/init/lib/grape/meta/subclasses.rb +20 -0
- data/samples/grape/init/lib/grape/xpath/app.rb +30 -0
- data/samples/grape/init/lib/grape/xpath/ruotes.rb +6 -0
- data/samples/grape/init/readme +1 -0
- data/samples/grape/readme +29 -0
- data/samples/grape/vendor/lib/grape/vendors/v1/rest.rb +57 -0
- data/samples/mongoid/cmd.yml +1 -0
- data/samples/mongoid/init/Gemfile +3 -0
- data/samples/mongoid/init/cmd.yml +2 -0
- data/samples/mongoid/init/docs/mongoid/ModelsRelations.rb +11 -0
- data/samples/mongoid/init/docs/mongoid/documents.xls +0 -0
- data/samples/mongoid/init/docs/mongoid/generate_modelsToDocs.rb +25 -0
- data/samples/mongoid/init/docs/mongoid/modelsToDocs.rb +25 -0
- data/samples/mongoid/init/docs/mongoid/relations.txt +1354 -0
- data/samples/mongoid/init/lib/mongoid.rb +44 -0
- data/samples/mongoid/init/lib/mongoid/dsl/extraDSL_CRUD.rb +446 -0
- data/samples/mongoid/init/lib/mongoid/dsl/extraDSL_MP.rb +517 -0
- data/samples/mongoid/init/lib/mongoid/dsl/init.rb +37 -0
- data/samples/mongoid/init/lib/mongoid/dsl/params.rb +67 -0
- data/samples/mongoid/init/lib/mongoid/meta/banned.rb +147 -0
- data/samples/mongoid/init/lib/mongoid/meta/control.yml +13 -0
- data/samples/mongoid/init/lib/mongoid/meta/mongoid.yml +6 -0
- data/samples/mongoid/init/lib/mongoid/meta/mpatch.rb +14 -0
- data/samples/mongoid/model/lib/mongoid/models/model.rb +28 -0
- data/samples/mongoid/readme +33 -0
- data/samples/rack/init/Gemfile +10 -0
- data/samples/rack/init/cmd.yml +2 -0
- data/samples/rack/init/config.ru +1 -0
- data/samples/rack/init/docs/rack/rake introducing.txt +60 -0
- data/samples/rack/init/docs/rack/webservers/Thin +43 -0
- data/samples/rack/init/docs/rack/webservers/ebb +72 -0
- data/samples/rack/init/docs/rack/webservers/fcgi +103 -0
- data/samples/rack/init/docs/rack/webservers/mongrel +74 -0
- data/samples/rack/init/docs/rack/webservers/passenger +37 -0
- data/samples/rack/init/docs/rack/webservers/scgi +188 -0
- data/samples/rack/init/lib/rack.rb +1 -0
- data/samples/rack/init/lib/rack/meta/webserver/thin.rb +45 -0
- data/samples/rack/init/lib/rack/meta/webserver/thin.yml +6 -0
- data/samples/rack/init/server.rb +0 -0
- data/samples/rack/readme +13 -0
- data/samples/rest_client/init/Gemfile +5 -0
- data/samples/rest_client/init/boot.rb +2 -0
- data/samples/rest_client/init/cmd.yml +1 -0
- data/samples/rest_client/init/config/rest_client/defaults.rb +16 -0
- data/samples/rest_client/init/docs/rest_client/simple overlook +251 -0
- data/samples/rest_client/init/test/rest_client/rest_dsl.rb +5 -0
- data/samples/rest_client/readme +7 -0
- data/samples/scripts/lines_counter/lines_number.rb +32 -0
- data/samples/scripts/lines_counter/readme +5 -0
- data/samples/scripts/readme +1 -0
- metadata +197 -7
- data/lib/clone/cms.rb +0 -56
- data/lib/clone/ext.rb +0 -77
- data/sample/test.rb +0 -30
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
require 'tempfile'
|
|
2
|
+
require 'shellwords'
|
|
3
|
+
|
|
4
|
+
module Commander
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
# = User Interaction
|
|
8
|
+
#
|
|
9
|
+
# Commander's user interaction module mixes in common
|
|
10
|
+
# methods which extend HighLine's functionality such
|
|
11
|
+
# as a #password method rather than calling #ask directly.
|
|
12
|
+
|
|
13
|
+
module UI
|
|
14
|
+
|
|
15
|
+
module_function
|
|
16
|
+
|
|
17
|
+
#--
|
|
18
|
+
# Auto include growl when available.
|
|
19
|
+
#++
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
require 'growl'
|
|
23
|
+
rescue LoadError
|
|
24
|
+
# Do nothing
|
|
25
|
+
else
|
|
26
|
+
include Growl
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Ask the user for a password. Specify a custom
|
|
31
|
+
# _message_ other than 'Password: ' or override the
|
|
32
|
+
# default _mask_ of '*'.
|
|
33
|
+
|
|
34
|
+
def password message = 'Password: ', mask = '*'
|
|
35
|
+
pass = ask(message) { |q| q.echo = mask }
|
|
36
|
+
pass = password message, mask if pass.nil? || pass.empty?
|
|
37
|
+
pass
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Choose from a set array of _choices_.
|
|
42
|
+
|
|
43
|
+
def choose message, *choices
|
|
44
|
+
say message
|
|
45
|
+
super(*choices)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# 'Log' an _action_ to the terminal. This is typically used
|
|
50
|
+
# for verbose output regarding actions performed. For example:
|
|
51
|
+
#
|
|
52
|
+
# create path/to/file.rb
|
|
53
|
+
# remove path/to/old_file.rb
|
|
54
|
+
# remove path/to/old_file2.rb
|
|
55
|
+
#
|
|
56
|
+
|
|
57
|
+
def log action, *args
|
|
58
|
+
say '%15s %s' % [action, args.join(' ')]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# 'Say' something using the OK color (green).
|
|
63
|
+
#
|
|
64
|
+
# === Examples
|
|
65
|
+
# say_ok 'Everything is fine'
|
|
66
|
+
# say_ok 'It is ok', 'This is ok too'
|
|
67
|
+
#
|
|
68
|
+
|
|
69
|
+
def say_ok *args
|
|
70
|
+
args.each do |arg|
|
|
71
|
+
say $terminal.color(arg, :green)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# 'Say' something using the WARNING color (yellow).
|
|
77
|
+
#
|
|
78
|
+
# === Examples
|
|
79
|
+
# say_warning 'This is a warning'
|
|
80
|
+
# say_warning 'Be careful', 'Think about it'
|
|
81
|
+
#
|
|
82
|
+
|
|
83
|
+
def say_warning *args
|
|
84
|
+
args.each do |arg|
|
|
85
|
+
say $terminal.color(arg, :yellow)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# 'Say' something using the ERROR color (red).
|
|
91
|
+
#
|
|
92
|
+
# === Examples
|
|
93
|
+
# say_error 'Everything is not fine'
|
|
94
|
+
# say_error 'It is not ok', 'This is not ok too'
|
|
95
|
+
#
|
|
96
|
+
|
|
97
|
+
def say_error *args
|
|
98
|
+
args.each do |arg|
|
|
99
|
+
say $terminal.color(arg, :red)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
##
|
|
104
|
+
# 'Say' something using the specified color
|
|
105
|
+
#
|
|
106
|
+
# === Examples
|
|
107
|
+
# color 'I am blue', :blue
|
|
108
|
+
# color 'I am bold', :bold
|
|
109
|
+
# color 'White on Red', :white, :on_red
|
|
110
|
+
#
|
|
111
|
+
# === Notes
|
|
112
|
+
# You may use:
|
|
113
|
+
# * color: black blue cyan green magenta red white yellow
|
|
114
|
+
# * style: blink bold clear underline
|
|
115
|
+
# * highligh: on_<color>
|
|
116
|
+
|
|
117
|
+
def color(*args)
|
|
118
|
+
say $terminal.color(*args)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# Speak _message_ using _voice_ which defaults
|
|
123
|
+
# to 'Alex', which is one of the better voices.
|
|
124
|
+
#
|
|
125
|
+
# === Examples
|
|
126
|
+
#
|
|
127
|
+
# speak 'What is your favorite food? '
|
|
128
|
+
# food = ask 'favorite food?: '
|
|
129
|
+
# speak "wow, I like #{food} too. We have so much alike."
|
|
130
|
+
#
|
|
131
|
+
# === Notes
|
|
132
|
+
#
|
|
133
|
+
# * MacOS only
|
|
134
|
+
#
|
|
135
|
+
|
|
136
|
+
def speak message, voice = :Alex
|
|
137
|
+
Thread.new { applescript "say #{message.inspect} using #{voice.to_s.inspect}" }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
##
|
|
141
|
+
# Converse with speech recognition.
|
|
142
|
+
#
|
|
143
|
+
# Currently a "poorman's" DSL to utilize applescript and
|
|
144
|
+
# the MacOS speech recognition server.
|
|
145
|
+
#
|
|
146
|
+
# === Examples
|
|
147
|
+
#
|
|
148
|
+
# case converse 'What is the best food?', :cookies => 'Cookies', :unknown => 'Nothing'
|
|
149
|
+
# when :cookies
|
|
150
|
+
# speak 'o.m.g. you are awesome!'
|
|
151
|
+
# else
|
|
152
|
+
# case converse 'That is lame, shall I convince you cookies are the best?', :yes => 'Ok', :no => 'No', :maybe => 'Maybe another time'
|
|
153
|
+
# when :yes
|
|
154
|
+
# speak 'Well you see, cookies are just fantastic.'
|
|
155
|
+
# else
|
|
156
|
+
# speak 'Ok then, bye.'
|
|
157
|
+
# end
|
|
158
|
+
# end
|
|
159
|
+
#
|
|
160
|
+
# === Notes
|
|
161
|
+
#
|
|
162
|
+
# * MacOS only
|
|
163
|
+
#
|
|
164
|
+
|
|
165
|
+
def converse prompt, responses = {}
|
|
166
|
+
i, commands = 0, responses.map { |key, value| value.inspect }.join(',')
|
|
167
|
+
statement = responses.inject '' do |statement, (key, value)|
|
|
168
|
+
statement << (((i += 1) == 1 ?
|
|
169
|
+
%(if response is "#{value}" then\n):
|
|
170
|
+
%(else if response is "#{value}" then\n))) <<
|
|
171
|
+
%(do shell script "echo '#{key}'"\n)
|
|
172
|
+
end
|
|
173
|
+
applescript(%(
|
|
174
|
+
tell application "SpeechRecognitionServer"
|
|
175
|
+
set response to listen for {#{commands}} with prompt "#{prompt}"
|
|
176
|
+
#{statement}
|
|
177
|
+
end if
|
|
178
|
+
end tell
|
|
179
|
+
)).strip.to_sym
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
##
|
|
183
|
+
# Execute apple _script_.
|
|
184
|
+
|
|
185
|
+
def applescript script
|
|
186
|
+
`osascript -e "#{ script.gsub('"', '\"') }"`
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
##
|
|
190
|
+
# Normalize IO streams, allowing for redirection of
|
|
191
|
+
# +input+ and/or +output+, for example:
|
|
192
|
+
#
|
|
193
|
+
# $ foo # => read from terminal I/O
|
|
194
|
+
# $ foo in # => read from 'in' file, output to terminal output stream
|
|
195
|
+
# $ foo in out # => read from 'in' file, output to 'out' file
|
|
196
|
+
# $ foo < in > out # => equivalent to above (essentially)
|
|
197
|
+
#
|
|
198
|
+
# Optionally a +block+ may be supplied, in which case
|
|
199
|
+
# IO will be reset once the block has executed.
|
|
200
|
+
#
|
|
201
|
+
# === Examples
|
|
202
|
+
#
|
|
203
|
+
# command :foo do |c|
|
|
204
|
+
# c.syntax = 'foo [input] [output]'
|
|
205
|
+
# c.when_called do |args, options|
|
|
206
|
+
# # or io(args.shift, args.shift)
|
|
207
|
+
# io *args
|
|
208
|
+
# str = $stdin.gets
|
|
209
|
+
# puts 'input was: ' + str.inspect
|
|
210
|
+
# end
|
|
211
|
+
# end
|
|
212
|
+
#
|
|
213
|
+
|
|
214
|
+
def io input = nil, output = nil, &block
|
|
215
|
+
$stdin = File.new(input) if input
|
|
216
|
+
$stdout = File.new(output, 'r+') if output
|
|
217
|
+
if block
|
|
218
|
+
yield
|
|
219
|
+
reset_io
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
##
|
|
224
|
+
# Reset IO to initial constant streams.
|
|
225
|
+
|
|
226
|
+
def reset_io
|
|
227
|
+
$stdin, $stdout = STDIN, STDOUT
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
##
|
|
231
|
+
# Find an editor available in path. Optionally supply the _preferred_
|
|
232
|
+
# editor. Returns the name as a string, nil if none is available.
|
|
233
|
+
|
|
234
|
+
def available_editor preferred = nil
|
|
235
|
+
[preferred, ENV['EDITOR'], 'mate -w', 'vim', 'vi', 'emacs', 'nano', 'pico'].
|
|
236
|
+
compact.
|
|
237
|
+
find {|name| system("hash #{name.split.first} 2>&-") }
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
##
|
|
241
|
+
# Prompt an editor for input. Optionally supply initial
|
|
242
|
+
# _input_ which is written to the editor.
|
|
243
|
+
#
|
|
244
|
+
# _preferred_editor_ can be hinted.
|
|
245
|
+
#
|
|
246
|
+
# === Examples
|
|
247
|
+
#
|
|
248
|
+
# ask_editor # => prompts EDITOR with no input
|
|
249
|
+
# ask_editor('foo') # => prompts EDITOR with default text of 'foo'
|
|
250
|
+
# ask_editor('foo', 'mate -w') # => prompts TextMate with default text of 'foo'
|
|
251
|
+
#
|
|
252
|
+
|
|
253
|
+
def ask_editor input = nil, preferred_editor = nil
|
|
254
|
+
editor = available_editor preferred_editor
|
|
255
|
+
program = Commander::Runner.instance.program(:name).downcase rescue 'commander'
|
|
256
|
+
tmpfile = Tempfile.new program
|
|
257
|
+
begin
|
|
258
|
+
tmpfile.write input if input
|
|
259
|
+
tmpfile.close
|
|
260
|
+
system("#{editor} #{tmpfile.path.shellescape}") ? IO.read(tmpfile.path) : nil
|
|
261
|
+
ensure
|
|
262
|
+
tmpfile.unlink
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
##
|
|
267
|
+
# Enable paging of output after called.
|
|
268
|
+
|
|
269
|
+
def enable_paging
|
|
270
|
+
return unless $stdout.tty?
|
|
271
|
+
return unless Process.respond_to? :fork
|
|
272
|
+
read, write = IO.pipe
|
|
273
|
+
|
|
274
|
+
# Kernel.fork is not supported on all platforms and configurations.
|
|
275
|
+
# As of Ruby 1.9, `Process.respond_to? :fork` should return false on
|
|
276
|
+
# configurations that don't support it, but versions before 1.9 don't
|
|
277
|
+
# seem to do this reliably and instead raise a NotImplementedError
|
|
278
|
+
# (which is rescued below).
|
|
279
|
+
|
|
280
|
+
if Kernel.fork
|
|
281
|
+
$stdin.reopen read
|
|
282
|
+
write.close; read.close
|
|
283
|
+
Kernel.select [$stdin]
|
|
284
|
+
ENV['LESS'] = 'FSRX'
|
|
285
|
+
pager = ENV['PAGER'] || 'less'
|
|
286
|
+
exec pager rescue exec '/bin/sh', '-c', pager
|
|
287
|
+
else
|
|
288
|
+
# subprocess
|
|
289
|
+
$stdout.reopen write
|
|
290
|
+
$stderr.reopen write if $stderr.tty?
|
|
291
|
+
write.close; read.close
|
|
292
|
+
end
|
|
293
|
+
rescue NotImplementedError
|
|
294
|
+
ensure
|
|
295
|
+
write.close if write && !write.closed?
|
|
296
|
+
read.close if read && !read.closed?
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
##
|
|
300
|
+
# Output progress while iterating _arr_.
|
|
301
|
+
#
|
|
302
|
+
# === Examples
|
|
303
|
+
#
|
|
304
|
+
# uris = %w( http://vision-media.ca http://google.com )
|
|
305
|
+
# progress uris, :format => "Remaining: :time_remaining" do |uri|
|
|
306
|
+
# res = open uri
|
|
307
|
+
# end
|
|
308
|
+
#
|
|
309
|
+
|
|
310
|
+
def progress arr, options = {}, &block
|
|
311
|
+
bar = ProgressBar.new arr.length, options
|
|
312
|
+
bar.show
|
|
313
|
+
arr.each { |v| bar.increment yield(v) }
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
##
|
|
317
|
+
# Implements ask_for_CLASS methods.
|
|
318
|
+
|
|
319
|
+
module AskForClass
|
|
320
|
+
# All special cases in HighLine::Question#convert, except those that implement #parse
|
|
321
|
+
([Float, Integer, String, Symbol, Regexp, Array, File, Pathname] +
|
|
322
|
+
# All Classes that respond to #parse
|
|
323
|
+
Object.constants.map do |const|
|
|
324
|
+
# const_get(:Config) issues a deprecation warning on ruby 1.8.7
|
|
325
|
+
Object.const_get(const) unless const == :Config
|
|
326
|
+
end.select do |const|
|
|
327
|
+
const.is_a? Class and const.respond_to? :parse
|
|
328
|
+
end).each do |klass|
|
|
329
|
+
define_method "ask_for_#{klass.to_s.downcase}" do |prompt|
|
|
330
|
+
$terminal.ask(prompt, klass)
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
##
|
|
336
|
+
# Substitute _hash_'s keys with their associated values in _str_.
|
|
337
|
+
|
|
338
|
+
def replace_tokens str, hash #:nodoc:
|
|
339
|
+
hash.inject str do |str, (key, value)|
|
|
340
|
+
str.gsub ":#{key}", value.to_s
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
##
|
|
345
|
+
# = Progress Bar
|
|
346
|
+
#
|
|
347
|
+
# Terminal progress bar utility. In its most basic form
|
|
348
|
+
# requires that the developer specifies when the bar should
|
|
349
|
+
# be incremented. Note that a hash of tokens may be passed to
|
|
350
|
+
# #increment, (or returned when using Object#progress).
|
|
351
|
+
#
|
|
352
|
+
# uris = %w(
|
|
353
|
+
# http://vision-media.ca
|
|
354
|
+
# http://yahoo.com
|
|
355
|
+
# http://google.com
|
|
356
|
+
# )
|
|
357
|
+
#
|
|
358
|
+
# bar = Commander::UI::ProgressBar.new uris.length, options
|
|
359
|
+
# threads = []
|
|
360
|
+
# uris.each do |uri|
|
|
361
|
+
# threads << Thread.new do
|
|
362
|
+
# begin
|
|
363
|
+
# res = open uri
|
|
364
|
+
# bar.increment :uri => uri
|
|
365
|
+
# rescue Exception => e
|
|
366
|
+
# bar.increment :uri => "#{uri} failed"
|
|
367
|
+
# end
|
|
368
|
+
# end
|
|
369
|
+
# end
|
|
370
|
+
# threads.each { |t| t.join }
|
|
371
|
+
#
|
|
372
|
+
# The Object method #progress is also available:
|
|
373
|
+
#
|
|
374
|
+
# progress uris, :width => 10 do |uri|
|
|
375
|
+
# res = open uri
|
|
376
|
+
# { :uri => uri } # Can now use :uri within :format option
|
|
377
|
+
# end
|
|
378
|
+
#
|
|
379
|
+
|
|
380
|
+
class ProgressBar
|
|
381
|
+
|
|
382
|
+
##
|
|
383
|
+
# Creates a new progress bar.
|
|
384
|
+
#
|
|
385
|
+
# === Options
|
|
386
|
+
#
|
|
387
|
+
# :title Title, defaults to "Progress"
|
|
388
|
+
# :width Width of :progress_bar
|
|
389
|
+
# :progress_str Progress string, defaults to "="
|
|
390
|
+
# :incomplete_str Incomplete bar string, defaults to '.'
|
|
391
|
+
# :format Defaults to ":title |:progress_bar| :percent_complete% complete "
|
|
392
|
+
# :tokens Additional tokens replaced within the format string
|
|
393
|
+
# :complete_message Defaults to "Process complete"
|
|
394
|
+
#
|
|
395
|
+
# === Tokens
|
|
396
|
+
#
|
|
397
|
+
# :title
|
|
398
|
+
# :percent_complete
|
|
399
|
+
# :progress_bar
|
|
400
|
+
# :step
|
|
401
|
+
# :steps_remaining
|
|
402
|
+
# :total_steps
|
|
403
|
+
# :time_elapsed
|
|
404
|
+
# :time_remaining
|
|
405
|
+
#
|
|
406
|
+
|
|
407
|
+
def initialize total, options = {}
|
|
408
|
+
@total_steps, @step, @start_time = total, 0, Time.now
|
|
409
|
+
@title = options.fetch :title, 'Progress'
|
|
410
|
+
@width = options.fetch :width, 25
|
|
411
|
+
@progress_str = options.fetch :progress_str, '='
|
|
412
|
+
@incomplete_str = options.fetch :incomplete_str, '.'
|
|
413
|
+
@complete_message = options.fetch :complete_message, 'Process complete'
|
|
414
|
+
@format = options.fetch :format, ':title |:progress_bar| :percent_complete% complete '
|
|
415
|
+
@tokens = options.fetch :tokens, {}
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
##
|
|
419
|
+
# Completion percentage.
|
|
420
|
+
|
|
421
|
+
def percent_complete
|
|
422
|
+
if @total_steps.zero?
|
|
423
|
+
100
|
|
424
|
+
else
|
|
425
|
+
@step * 100 / @total_steps
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
##
|
|
430
|
+
# Time that has elapsed since the operation started.
|
|
431
|
+
|
|
432
|
+
def time_elapsed
|
|
433
|
+
Time.now - @start_time
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
##
|
|
437
|
+
# Estimated time remaining.
|
|
438
|
+
|
|
439
|
+
def time_remaining
|
|
440
|
+
(time_elapsed / @step) * steps_remaining
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
##
|
|
444
|
+
# Number of steps left.
|
|
445
|
+
|
|
446
|
+
def steps_remaining
|
|
447
|
+
@total_steps - @step
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
##
|
|
451
|
+
# Formatted progress bar.
|
|
452
|
+
|
|
453
|
+
def progress_bar
|
|
454
|
+
(@progress_str * (@width * percent_complete / 100)).ljust @width, @incomplete_str
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
##
|
|
458
|
+
# Generates tokens for this step.
|
|
459
|
+
|
|
460
|
+
def generate_tokens
|
|
461
|
+
{
|
|
462
|
+
:title => @title,
|
|
463
|
+
:percent_complete => percent_complete,
|
|
464
|
+
:progress_bar => progress_bar,
|
|
465
|
+
:step => @step,
|
|
466
|
+
:steps_remaining => steps_remaining,
|
|
467
|
+
:total_steps => @total_steps,
|
|
468
|
+
:time_elapsed => "%0.2fs" % time_elapsed,
|
|
469
|
+
:time_remaining => @step > 0 ? "%0.2fs" % time_remaining : '',
|
|
470
|
+
}.
|
|
471
|
+
merge! @tokens
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
##
|
|
475
|
+
# Output the progress bar.
|
|
476
|
+
|
|
477
|
+
def show
|
|
478
|
+
unless finished?
|
|
479
|
+
erase_line
|
|
480
|
+
if completed?
|
|
481
|
+
$terminal.say UI.replace_tokens(@complete_message, generate_tokens) if @complete_message.is_a? String
|
|
482
|
+
else
|
|
483
|
+
$terminal.say UI.replace_tokens(@format, generate_tokens) << ' '
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
##
|
|
489
|
+
# Whether or not the operation is complete, and we have finished.
|
|
490
|
+
|
|
491
|
+
def finished?
|
|
492
|
+
@step == @total_steps + 1
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
##
|
|
496
|
+
# Whether or not the operation has completed.
|
|
497
|
+
|
|
498
|
+
def completed?
|
|
499
|
+
@step == @total_steps
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
##
|
|
503
|
+
# Increment progress. Optionally pass _tokens_ which
|
|
504
|
+
# can be displayed in the output format.
|
|
505
|
+
|
|
506
|
+
def increment tokens = {}
|
|
507
|
+
@step += 1
|
|
508
|
+
@tokens.merge! tokens if tokens.is_a? Hash
|
|
509
|
+
show
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
##
|
|
513
|
+
# Erase previous terminal line.
|
|
514
|
+
|
|
515
|
+
def erase_line
|
|
516
|
+
# highline does not expose the output stream
|
|
517
|
+
$terminal.instance_variable_get('@output').print "\r\e[K"
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
end
|