tty-command 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +3 -0
- data/.travis.yml +25 -0
- data/CHANGELOG.md +7 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +392 -0
- data/Rakefile +10 -0
- data/bin/console +6 -0
- data/bin/setup +6 -0
- data/examples/bash.rb +12 -0
- data/examples/basic.rb +9 -0
- data/examples/env.rb +9 -0
- data/examples/logger.rb +10 -0
- data/examples/redirect_stderr.rb +10 -0
- data/examples/redirect_stdout.rb +7 -0
- data/examples/timeout.rb +7 -0
- data/lib/tty-command.rb +1 -0
- data/lib/tty/command.rb +160 -0
- data/lib/tty/command/cmd.rb +153 -0
- data/lib/tty/command/dry_runner.rb +19 -0
- data/lib/tty/command/execute.rb +134 -0
- data/lib/tty/command/exit_error.rb +28 -0
- data/lib/tty/command/printers/abstract.rb +50 -0
- data/lib/tty/command/printers/null.rb +15 -0
- data/lib/tty/command/printers/pretty.rb +67 -0
- data/lib/tty/command/printers/progress.rb +31 -0
- data/lib/tty/command/printers/quiet.rb +25 -0
- data/lib/tty/command/process_runner.rb +101 -0
- data/lib/tty/command/result.rb +72 -0
- data/lib/tty/command/truncator.rb +109 -0
- data/lib/tty/command/version.rb +7 -0
- data/tasks/console.rake +10 -0
- data/tasks/coverage.rake +11 -0
- data/tasks/spec.rake +29 -0
- data/tty-command.gemspec +27 -0
- metadata +146 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1fc9ae4bb4984bdcf9fdc7a49fd6b9b912ff60a2
|
4
|
+
data.tar.gz: d47f52018f538b780aac9eba1abafcf696d1ebd7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6b4b96a1351485b1b4fa436a58adc71d08f91f21e81f2f4cdeea78b10773bce7d5681e6340add08d963a57e17183b65799c17fc2d74ec32c48c5b325950994e6
|
7
|
+
data.tar.gz: ba6f5e69a2588cdf37f33bea99e10147ccc0b0d0b5f3f91dd6d0b24ec44cac7b24627184644ac07627557d91de950f42012c6cfdebab5eea644f900a72e8d598
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
language: ruby
|
3
|
+
sudo: false
|
4
|
+
cache: bundler
|
5
|
+
script: "bundle exec rake ci"
|
6
|
+
rvm:
|
7
|
+
- 1.9.3
|
8
|
+
- 2.0
|
9
|
+
- 2.1
|
10
|
+
- 2.2
|
11
|
+
- 2.3.0
|
12
|
+
- ruby-head
|
13
|
+
- jruby
|
14
|
+
- jruby-9000
|
15
|
+
- rbx-2
|
16
|
+
matrix:
|
17
|
+
allow_failures:
|
18
|
+
- rvm: ruby-head
|
19
|
+
- rvm: jruby
|
20
|
+
- rvm: jruby-9000
|
21
|
+
fast_finish: true
|
22
|
+
branches:
|
23
|
+
only: master
|
24
|
+
notifications:
|
25
|
+
email: false
|
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at [email]. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Piotr Murach
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,392 @@
|
|
1
|
+
# TTY::Command [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/tty-command.svg)][gem]
|
3
|
+
[![Build Status](https://secure.travis-ci.org/piotrmurach/tty-command.svg?branch=master)][travis]
|
4
|
+
[![Code Climate](https://codeclimate.com/github/piotrmurach/tty-command/badges/gpa.svg)][codeclimate]
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-command/badge.svg)][coverage]
|
6
|
+
[![Inline docs](http://inch-ci.org/github/piotrmurach/tty-command.svg?branch=master)][inchpages]
|
7
|
+
|
8
|
+
[gitter]: https://gitter.im/piotrmurach/tty
|
9
|
+
[gem]: http://badge.fury.io/rb/tty-command
|
10
|
+
[travis]: http://travis-ci.org/piotrmurach/tty-command
|
11
|
+
[codeclimate]: https://codeclimate.com/github/piotrmurach/tty-command
|
12
|
+
[coverage]: https://coveralls.io/github/piotrmurach/tty-command
|
13
|
+
[inchpages]: http://inch-ci.org/github/piotrmurach/tty-command
|
14
|
+
|
15
|
+
> Run external commands with pretty output logging and capture stdout, stderr and exit status. Redirect stdin, stdout and stderr of each command to a file or a string.
|
16
|
+
|
17
|
+
**TTY::Command** provides independent command execution component for [TTY](https://github.com/piotrmurach/tty) toolkit.
|
18
|
+
|
19
|
+
## Motivation
|
20
|
+
|
21
|
+
Complex software projects aren't just a single app. These projects usually spawn dozens or hundreds of supplementary standalone scripts which are just as important as the app itself. Examples include - data validation, deployment, monitoring, database maintenance, backup & restore, configuration management, crawling, ETL, analytics, log file processing, custom reports, etc. One of the contributors to **TTY::Command** counted 222 scripts in the `bin` directory for his startup.
|
22
|
+
|
23
|
+
Why should we be handcuffed to `sh` or `bash` for these scripts when we could be using Ruby? Ruby is easier to write and more fun, and we gain a lot by using a better language. It's nice for everyone to just use Ruby everywhere.
|
24
|
+
|
25
|
+
**TTY::Command** tries to add value in other ways. It'll halt automatically if a command fails. It's easy to get verbose or quiet output as appropriate, or even capture output and parse it with Ruby. Escaping arguments is a breeze. These are all areas where traditional shell scripts tend to fall flat.
|
26
|
+
|
27
|
+
## Installation
|
28
|
+
|
29
|
+
Add this line to your application's Gemfile:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
gem 'tty-command'
|
33
|
+
```
|
34
|
+
|
35
|
+
And then execute:
|
36
|
+
|
37
|
+
$ bundle
|
38
|
+
|
39
|
+
Or install it yourself as:
|
40
|
+
|
41
|
+
$ gem install tty-command
|
42
|
+
|
43
|
+
## Contents
|
44
|
+
|
45
|
+
* [1. Usage](#1-usage)
|
46
|
+
* [2. Interface](#2-interface)
|
47
|
+
* [2.1. Run](#21-run)
|
48
|
+
* [2.2. Run!](#22-run)
|
49
|
+
* [2.3. Test](#23-test)
|
50
|
+
* [2.4. Logging](#24-logging)
|
51
|
+
* [2.5. Dry run](#25-dry-run)
|
52
|
+
* [3. Advanced Interface](#3-advanced-interface)
|
53
|
+
* [3.1. Environment variables](#31-environment-variables)
|
54
|
+
* [3.2. Options](#32-options)
|
55
|
+
* [3.2.1. Current directory](#321-current-directory)
|
56
|
+
* [3.2.2. Redirection](#322-redirection)
|
57
|
+
* [3.2.3. Timeout](#323-timeout)
|
58
|
+
* [3.2.4. User](#324-user)
|
59
|
+
* [3.2.5. Group](#325-group)
|
60
|
+
* [3.2.6. Umask](#326-umask)
|
61
|
+
* [3.3. Result](#33-result)
|
62
|
+
* [3.3.1. success?](#331-success)
|
63
|
+
* [3.3.2. failure?](#332-failure)
|
64
|
+
* [3.3.3. exited?](#333-exited)
|
65
|
+
* [3.4. Custom printer](#34-custom-printer)
|
66
|
+
* [4. Example](#4-example)
|
67
|
+
|
68
|
+
## 1. Usage
|
69
|
+
|
70
|
+
Create a command instance and then run some commands:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
cmd = TTY::Command.new
|
74
|
+
cmd.run('ls -la')
|
75
|
+
cmd.run('echo Hello!')
|
76
|
+
```
|
77
|
+
|
78
|
+
Note that `run` will throw an exception if the command fails. This is already an improvement over ordinary shell scripts, which just keep on going when things go bad. That usually makes things worse.
|
79
|
+
|
80
|
+
You can use the return value to capture stdout and stderr:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
out, err = cmd.run('cat ~/.bashrc | grep alias')
|
84
|
+
```
|
85
|
+
|
86
|
+
Instead of using a plain old string, you can break up the arguments and they'll get escaped if necessary:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
path = "hello world"
|
90
|
+
FileUtils.touch(path)
|
91
|
+
cmd.run("sum #{path}") # this will fail due to bad escaping
|
92
|
+
cmd.run("sum", path) # this gets escaped automatically
|
93
|
+
```
|
94
|
+
|
95
|
+
## 2. Interface
|
96
|
+
|
97
|
+
### 2.1 Run
|
98
|
+
|
99
|
+
Run starts the specified command and waits for it to complete.
|
100
|
+
|
101
|
+
The argument signature of `run` is as follows:
|
102
|
+
|
103
|
+
`run([env], command, [argv1, ...], [options])`
|
104
|
+
|
105
|
+
The `env`, `command` and `options` arguments are described in the following sections.
|
106
|
+
|
107
|
+
For example, to display file contents:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
cmd.run('cat file.txt')
|
111
|
+
```
|
112
|
+
|
113
|
+
If the command succeeds, a `TTY::Command::Result` is returned that records stdout and stderr:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
out, err = cmd.run('date')
|
117
|
+
puts "The date is #{out}"
|
118
|
+
# => "The date is Tue 10 May 2016 22:30:15 BST\n"
|
119
|
+
```
|
120
|
+
|
121
|
+
If the command fails (with a non-zero exit code), a `TTY::Command::ExitError` is raised. The `ExitError` message will include:
|
122
|
+
|
123
|
+
* the name of command executed
|
124
|
+
* the exit status
|
125
|
+
* stdout bytes
|
126
|
+
* stderr bytes
|
127
|
+
|
128
|
+
If the error output is very long, the stderr may contain only a prefix, number of omitted bytes and suffix.
|
129
|
+
|
130
|
+
### 2.2 Run!
|
131
|
+
|
132
|
+
If you expect a command to fail occasionally, use `run!` instead. Then you can detect failures and respond appropriately. For example:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
if cmd.run!('which xyzzy').failure?
|
136
|
+
cmd.run('brew install xyzzy')
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
### 2.3 Test
|
141
|
+
|
142
|
+
To simulate classic bash test command you case use `test` method with expression to check as a first argument:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
if cmd.test '-e /etc/passwd'
|
146
|
+
puts "Sweet..."
|
147
|
+
else
|
148
|
+
puts "Ohh no! Where is it?"
|
149
|
+
exit 1
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
153
|
+
### 2.4 Logging
|
154
|
+
|
155
|
+
By default, when a command is run, the command and the output are printed to `stdout` using the `:pretty` printer. If you wish to change printer you can do so by passing a `:printer` option:
|
156
|
+
|
157
|
+
* `:null` - no output
|
158
|
+
* `:pretty` - colorful output
|
159
|
+
* `:progress` - minimal output with green dot for success and F for failure
|
160
|
+
* `:quiet` - only output actual command stdout and stderr
|
161
|
+
|
162
|
+
like so:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
cmd = TTY::Command.new(printer: :progress)
|
166
|
+
```
|
167
|
+
|
168
|
+
By default the printers log to `stdout` but this can be changed by passing an object that responds to `<<` message:
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
logger = Logger.new('dev.log')
|
172
|
+
cmd = TTY::Command.new(output: output)
|
173
|
+
```
|
174
|
+
|
175
|
+
You can force the printer to always in print in color by passing the `:color` option:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
cmd = TTY::Command.new(color: true)
|
179
|
+
```
|
180
|
+
|
181
|
+
### 2.5 Dry run
|
182
|
+
|
183
|
+
Sometimes it can be useful to put your script into a "dry run" mode that prints commands without actually running them. To simulate execution of the command use the `:dry_run` option:
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
cmd = TTY::Command.new(dry_run: true)
|
187
|
+
cmd.run(:rm, 'all_my_files')
|
188
|
+
# => [123abc] (dry run) rm all_my_files
|
189
|
+
```
|
190
|
+
|
191
|
+
To check what mode the command is in use the `dry_run?` query helper:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
cmd.dry_run? # => true
|
195
|
+
```
|
196
|
+
|
197
|
+
## 3. Advanced Interface
|
198
|
+
|
199
|
+
### 3.1 Environment variables
|
200
|
+
|
201
|
+
The environment variables need to be provided as hash entries, that can be set directly as a first argument:
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
cmd.run({'RAILS_ENV' => 'PRODUCTION'}, :rails, 'server')
|
205
|
+
```
|
206
|
+
|
207
|
+
or as an option with `:env` key:
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
cmd.run(:rails, 'server', env: {rails_env: :production})
|
211
|
+
```
|
212
|
+
|
213
|
+
When a value in env is nil, the variable is unset in the child process:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
cmd.run(:echo, 'hello', env: {foo: 'bar', baz: nil})
|
217
|
+
```
|
218
|
+
|
219
|
+
### 3.2 Options
|
220
|
+
|
221
|
+
When a hash is given in the last argument (options), it allows to specify a current directory, umask, user, group and and zero or more fd redirects for the child process.
|
222
|
+
|
223
|
+
#### 3.2.1 Current directory
|
224
|
+
|
225
|
+
To change directory in which the command is run pass the `:chidir` option:
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
cmd.run(:echo, 'hello', chdir: '/var/tmp')
|
229
|
+
```
|
230
|
+
|
231
|
+
#### 3.2.2 Redirection
|
232
|
+
|
233
|
+
The streams can be redirected using hash keys `:in`, `:out`, `:err`, a fixnum, an IO and array. The keys specify a given file descriptor for the child process.
|
234
|
+
|
235
|
+
You can specify a filename for redirection as a hash value:
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
cmd.run(:ls, :in => "/dev/null") # read mode
|
239
|
+
cmd.run(:ls, :out => "/dev/null") # write mode
|
240
|
+
cmd.run(:ls, :err => "log") # write mode
|
241
|
+
cmd.run(:ls, [:out, :err] => "/dev/null") # write mode
|
242
|
+
cmd.run(:ls, 3 => "/dev/null") # read mode
|
243
|
+
```
|
244
|
+
|
245
|
+
You can also provide actual file descriptor for redirection:
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
cmd.run(:cat, :in => open('/etc/passwd'))
|
249
|
+
```
|
250
|
+
|
251
|
+
For example, to merge stderr into stdout you would do:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
cmd.run(:ls, '-la', :stderr => :stdout)
|
255
|
+
cmd.run(:ls, '-la', 2 => 1)
|
256
|
+
```
|
257
|
+
|
258
|
+
#### 3.2.3 Timeout
|
259
|
+
|
260
|
+
You can timeout command execuation by providing the `:timeout` option in seconds:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
cmd.run("while test 1; sleep 1; done", timeout: 5)
|
264
|
+
```
|
265
|
+
|
266
|
+
Please run `examples/timeout.rb` to see timeout in action.
|
267
|
+
|
268
|
+
#### 3.2.4 User
|
269
|
+
|
270
|
+
To run command as a given user do:
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
cmd.run(:echo, 'hello', user: 'piotr')
|
274
|
+
```
|
275
|
+
|
276
|
+
#### 3.2.5 Group
|
277
|
+
|
278
|
+
To run command as part of group do:
|
279
|
+
|
280
|
+
```ruby
|
281
|
+
cmd.run(:echo, 'hello', group: 'devs')
|
282
|
+
```
|
283
|
+
|
284
|
+
#### 3.2.6 Umask
|
285
|
+
|
286
|
+
To run command with umask do:
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
cmd.run(:echo, 'hello', umask: '007')
|
290
|
+
```
|
291
|
+
|
292
|
+
### 3.3 Result
|
293
|
+
|
294
|
+
Each time you run command the stdout and stderr are captured and return as result. The result can be examined directly by casting it to tuple:
|
295
|
+
|
296
|
+
```ruby
|
297
|
+
out, err = cmd.run(:echo, 'Hello')
|
298
|
+
```
|
299
|
+
|
300
|
+
However, if you want to you can defer reading:
|
301
|
+
|
302
|
+
```ruby
|
303
|
+
result = cmd.run(:echo, 'Hello')
|
304
|
+
result.out
|
305
|
+
result.err
|
306
|
+
```
|
307
|
+
|
308
|
+
#### 3.3.1 success?
|
309
|
+
|
310
|
+
To check if command exited successfully use `success?`:
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
result = cmd.run(:echo, 'Hello')
|
314
|
+
result.success? # => true
|
315
|
+
```
|
316
|
+
|
317
|
+
#### 3.3.2 failure?
|
318
|
+
|
319
|
+
To check if command exited unsuccessfully use `failure?` or `failed?`:
|
320
|
+
|
321
|
+
```ruby
|
322
|
+
result = cmd.run(:echo, 'Hello')
|
323
|
+
result.failure? # => false
|
324
|
+
result.failed? # => false
|
325
|
+
```
|
326
|
+
|
327
|
+
#### 3.3.3 exited?
|
328
|
+
|
329
|
+
To check if command run to complition use `exited?` or `complete?`:
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
result = cmd.run(:echo, 'Hello')
|
333
|
+
result.exited? # => true
|
334
|
+
result.complete? # => true
|
335
|
+
```
|
336
|
+
|
337
|
+
### 3.4 Custom printer
|
338
|
+
|
339
|
+
If the built-in printers do not meet your requirements you can create your own. At the very minimum you need to specify the `write` method that will be called during the lifecycle of command execution:
|
340
|
+
|
341
|
+
```ruby
|
342
|
+
CustomPrinter < TTY::Command::Printers::Abstract
|
343
|
+
def write(message)
|
344
|
+
puts message
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
printer = CustomPrinter
|
349
|
+
|
350
|
+
cmd = TTY::Command.new(printer: printer)
|
351
|
+
```
|
352
|
+
|
353
|
+
## 4. Example
|
354
|
+
|
355
|
+
Here's a slightly more elaborate example to illustrate how tty-command can improve on plain old shell scripts. This example installs a new version of Ruby on an Ubuntu machine.
|
356
|
+
|
357
|
+
```ruby
|
358
|
+
cmd = TTY::Command.new
|
359
|
+
|
360
|
+
# dependencies
|
361
|
+
cmd.run "apt-get -y install build-essential checkinstall"
|
362
|
+
|
363
|
+
# fetch ruby if necessary
|
364
|
+
if !File.exists?("ruby-2.3.0.tar.gz")
|
365
|
+
puts "Downloading..."
|
366
|
+
cmd.run "wget http://ftp.ruby-lang.org/pub/ruby/2.3/ruby-2.3.0.tar.gz"
|
367
|
+
cmd.run "tar xvzf ruby-2.3.0.tar.gz"
|
368
|
+
end
|
369
|
+
|
370
|
+
# now install
|
371
|
+
Dir.chdir("ruby-2.3.0") do
|
372
|
+
puts "Building..."
|
373
|
+
cmd.run "./configure --prefix=/usr/local"
|
374
|
+
cmd.run "make"
|
375
|
+
end
|
376
|
+
```
|
377
|
+
|
378
|
+
## Development
|
379
|
+
|
380
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
381
|
+
|
382
|
+
## Contributing
|
383
|
+
|
384
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/tty-command. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
385
|
+
|
386
|
+
## License
|
387
|
+
|
388
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
389
|
+
|
390
|
+
## Copyright
|
391
|
+
|
392
|
+
Copyright (c) 2016 Piotr Murach. See LICENSE for further details.
|