tty 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +9 -9
- data/CHANGELOG.md +27 -10
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +2 -2
- data/README.md +40 -182
- data/appveyor.yml +23 -0
- data/lib/tty.rb +2 -65
- data/lib/tty/plugins.rb +46 -19
- data/lib/tty/plugins/plugin.rb +4 -9
- data/lib/tty/version.rb +1 -1
- data/spec/fixtures/foo-0.0.1.gemspec +17 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/tty/plugins/find_spec.rb +11 -19
- data/spec/tty/plugins/load_spec.rb +6 -10
- data/spec/tty/plugins/plugin/load_spec.rb +15 -5
- data/spec/tty/plugins/plugin/new_spec.rb +3 -6
- data/spec/tty/tty_spec.rb +1 -7
- data/tty.gemspec +11 -9
- metadata +89 -94
- data/lib/tty/logger.rb +0 -85
- data/lib/tty/support/coercion.rb +0 -30
- data/lib/tty/support/delegatable.rb +0 -44
- data/lib/tty/support/unicode.rb +0 -35
- data/lib/tty/system.rb +0 -14
- data/lib/tty/system/editor.rb +0 -114
- data/lib/tty/terminal.rb +0 -21
- data/lib/tty/terminal/home.rb +0 -42
- data/lib/tty/vector.rb +0 -116
- data/spec/tty/logger/log_spec.rb +0 -23
- data/spec/tty/logger/new_spec.rb +0 -36
- data/spec/tty/logger/valid_level_spec.rb +0 -33
- data/spec/tty/support/coercion_spec.rb +0 -41
- data/spec/tty/support/delegatable_spec.rb +0 -28
- data/spec/tty/support/fixtures/classes.rb +0 -19
- data/spec/tty/system/editor/available_spec.rb +0 -40
- data/spec/tty/system/editor/build_spec.rb +0 -32
- data/spec/tty/system/editor/command_spec.rb +0 -17
- data/spec/tty/system/editor/executables_spec.rb +0 -13
- data/spec/tty/system/editor/invoke_spec.rb +0 -34
- data/spec/tty/system/editor/open_spec.rb +0 -29
- data/spec/tty/terminal/home_spec.rb +0 -27
- data/spec/tty/vector/new_spec.rb +0 -48
data/lib/tty/support/coercion.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
# A mixin to coerce a value into a specific class.
|
5
|
-
module Coercion
|
6
|
-
# Helper to coerce value into a specific class.
|
7
|
-
#
|
8
|
-
# @param [Object] object
|
9
|
-
#
|
10
|
-
# @param [Class] cls
|
11
|
-
#
|
12
|
-
# @param [Symbol] method
|
13
|
-
#
|
14
|
-
# @api public
|
15
|
-
def coerce_to(object, cls, method)
|
16
|
-
return object if object.is_a?(cls)
|
17
|
-
|
18
|
-
begin
|
19
|
-
result = object.__send__(method)
|
20
|
-
rescue Exception => e
|
21
|
-
raise TypeError, "Coercion error #{e.message}"
|
22
|
-
end
|
23
|
-
unless result.is_a?(cls)
|
24
|
-
fail TypeError, "Coercion error: obj.#{method} did not return " \
|
25
|
-
"a #{cls} (was #{result.class})"
|
26
|
-
end
|
27
|
-
result
|
28
|
-
end
|
29
|
-
end # Coercion
|
30
|
-
end # TTY
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
# A mixin to allow delegetable methods to be added
|
5
|
-
module Delegatable
|
6
|
-
# Create delegator for each specified method
|
7
|
-
#
|
8
|
-
# @example
|
9
|
-
# delegatable_method :source, :method
|
10
|
-
#
|
11
|
-
# @param [Symbol] source
|
12
|
-
#
|
13
|
-
# @param [Array] methods
|
14
|
-
#
|
15
|
-
# @return [self]
|
16
|
-
#
|
17
|
-
# @api public
|
18
|
-
def delegatable_method(source, *methods)
|
19
|
-
methods.each do |method|
|
20
|
-
define_delegatable_method(source, method)
|
21
|
-
end
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
# Create a delegator method for the method name
|
28
|
-
#
|
29
|
-
# @param [Symbol] source
|
30
|
-
#
|
31
|
-
# @param [Symbol] method name
|
32
|
-
#
|
33
|
-
# @return [undefined]
|
34
|
-
#
|
35
|
-
# @api private
|
36
|
-
def define_delegatable_method(source, method)
|
37
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
38
|
-
def #{method}(*args, &block)
|
39
|
-
#{source}.#{method}(*args, &block)
|
40
|
-
end
|
41
|
-
RUBY
|
42
|
-
end
|
43
|
-
end # Delegatable
|
44
|
-
end # TTY
|
data/lib/tty/support/unicode.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
# A mixin to provide unicode support.
|
5
|
-
module Unicode
|
6
|
-
|
7
|
-
def utf8?(string)
|
8
|
-
string.unpack('U*') rescue return false
|
9
|
-
true
|
10
|
-
end
|
11
|
-
|
12
|
-
def clean_utf8(string)
|
13
|
-
require 'iconv'
|
14
|
-
if defined? ::Iconv
|
15
|
-
converter = Iconv.new('UTF-8//IGNORE', 'UTF-8')
|
16
|
-
converter.iconv(string)
|
17
|
-
end
|
18
|
-
rescue Exception
|
19
|
-
string
|
20
|
-
end
|
21
|
-
|
22
|
-
if ''.respond_to?(:encode)
|
23
|
-
def as_unicode
|
24
|
-
yield
|
25
|
-
end
|
26
|
-
else
|
27
|
-
def as_unicode
|
28
|
-
old, $KCODE = $KCODE, 'U'
|
29
|
-
yield
|
30
|
-
ensure
|
31
|
-
$KCODE = old
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end # Unicode
|
35
|
-
end # TTY
|
data/lib/tty/system.rb
DELETED
data/lib/tty/system/editor.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'shellwords'
|
4
|
-
|
5
|
-
module TTY
|
6
|
-
class System
|
7
|
-
# A class responsible for launching an editor
|
8
|
-
#
|
9
|
-
# @api private
|
10
|
-
class Editor
|
11
|
-
attr_reader :file
|
12
|
-
|
13
|
-
@command = nil
|
14
|
-
|
15
|
-
# Initialize an Editor
|
16
|
-
#
|
17
|
-
# @param [String] file
|
18
|
-
#
|
19
|
-
# @api public
|
20
|
-
def initialize(file)
|
21
|
-
@file = file
|
22
|
-
end
|
23
|
-
|
24
|
-
# List possible executable for editor command
|
25
|
-
#
|
26
|
-
# @return [Array[String]]
|
27
|
-
#
|
28
|
-
# @api private
|
29
|
-
def self.executables
|
30
|
-
[ENV['VISUAL'], ENV['EDITOR'], 'vi', 'emacs']
|
31
|
-
end
|
32
|
-
|
33
|
-
# Find available command
|
34
|
-
#
|
35
|
-
# @param [Array[String]] commands
|
36
|
-
#
|
37
|
-
# @return [String]
|
38
|
-
#
|
39
|
-
# @api public
|
40
|
-
def self.available(*commands)
|
41
|
-
commands = commands.empty? ? executables : commands
|
42
|
-
commands.compact.uniq.find { |cmd| System.exists?(cmd) }
|
43
|
-
end
|
44
|
-
|
45
|
-
# Finds command using a configured command(s) or detected shell commands.
|
46
|
-
#
|
47
|
-
# @param [Array[String]] commands
|
48
|
-
#
|
49
|
-
# @return [String]
|
50
|
-
#
|
51
|
-
# @api public
|
52
|
-
def self.command(*commands)
|
53
|
-
@command = if @command && commands.empty?
|
54
|
-
@command
|
55
|
-
else
|
56
|
-
available(*commands)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Open file in system editor
|
61
|
-
#
|
62
|
-
# @param [String] file
|
63
|
-
# the name of the file
|
64
|
-
#
|
65
|
-
# @raise [TTY::CommandInvocationError]
|
66
|
-
#
|
67
|
-
# @return [Object]
|
68
|
-
#
|
69
|
-
# @api public
|
70
|
-
def self.open(file)
|
71
|
-
unless command
|
72
|
-
fail CommandInvocationError, 'Please export $VISUAL or $EDITOR'
|
73
|
-
end
|
74
|
-
|
75
|
-
new(file).invoke
|
76
|
-
end
|
77
|
-
|
78
|
-
# Build invocation command for editor
|
79
|
-
#
|
80
|
-
# @return [String]
|
81
|
-
#
|
82
|
-
# @api private
|
83
|
-
def build
|
84
|
-
"#{Editor.command} #{escape_file}"
|
85
|
-
end
|
86
|
-
|
87
|
-
# Escape file path
|
88
|
-
#
|
89
|
-
# @api private
|
90
|
-
def escape_file
|
91
|
-
if System.unix?
|
92
|
-
# Escape file string so it can be safely used in a Bourne shell
|
93
|
-
Shellwords.shellescape(file)
|
94
|
-
elsif System.windows?
|
95
|
-
file.gsub(/\//, '\\')
|
96
|
-
else
|
97
|
-
file
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# Inovke editor command in a shell
|
102
|
-
#
|
103
|
-
# @raise [TTY::CommandInvocationError]
|
104
|
-
#
|
105
|
-
# @api private
|
106
|
-
def invoke
|
107
|
-
command_invocation = build
|
108
|
-
status = system(*Shellwords.split(command_invocation))
|
109
|
-
return status if status
|
110
|
-
fail CommandInvocationError, "`#{command_invocation}` failed with status: #{$? ? $?.exitstatus : nil}"
|
111
|
-
end
|
112
|
-
end # Editor
|
113
|
-
end # System
|
114
|
-
end # TTY
|
data/lib/tty/terminal.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
class Terminal
|
5
|
-
# Initialize a Terminal
|
6
|
-
#
|
7
|
-
# @api public
|
8
|
-
def initialize(options = {})
|
9
|
-
@home = Home.new
|
10
|
-
end
|
11
|
-
|
12
|
-
# Find user home directory
|
13
|
-
#
|
14
|
-
# @return [String]
|
15
|
-
#
|
16
|
-
# @api public
|
17
|
-
def home
|
18
|
-
@home.find_home
|
19
|
-
end
|
20
|
-
end # Terminal
|
21
|
-
end # TTY
|
data/lib/tty/terminal/home.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
class Terminal
|
5
|
-
# A class responsible for locating user home
|
6
|
-
class Home
|
7
|
-
# @api public
|
8
|
-
def initialize(platform = nil)
|
9
|
-
@platform = platform || TTY::Platform
|
10
|
-
end
|
11
|
-
|
12
|
-
# Find user home
|
13
|
-
#
|
14
|
-
# @api public
|
15
|
-
def find_home
|
16
|
-
path = @platform.windows? ? windows_home : unix_home
|
17
|
-
File.expand_path(path)
|
18
|
-
end
|
19
|
-
|
20
|
-
def unix_home
|
21
|
-
require 'etc'
|
22
|
-
"~#{Etc.getlogin}"
|
23
|
-
rescue
|
24
|
-
ENV['HOME']
|
25
|
-
end
|
26
|
-
|
27
|
-
def windows_home
|
28
|
-
if (home = ENV['HOME'])
|
29
|
-
home.tr('\\', '/')
|
30
|
-
elsif ENV['HOMEDRIVE'] && ENV['HOMEPATH']
|
31
|
-
File.join(ENV['HOMEDRIVE'], ENV['HOMEPATH'])
|
32
|
-
elsif ENV['USERPROFILE']
|
33
|
-
ENV['USERPROFILE']
|
34
|
-
elsif ENV['HOMEDRIVE'] || ENV['SystemDrive']
|
35
|
-
File.join(ENV['HOMEDRIVE'] || ENV['SystemDrive'], '/')
|
36
|
-
else
|
37
|
-
'C:/'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end # Home
|
41
|
-
end # Terminal
|
42
|
-
end # TTY
|
data/lib/tty/vector.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
# This class represents a mathematical vector.
|
5
|
-
class Vector
|
6
|
-
include Enumerable, Equatable
|
7
|
-
|
8
|
-
attr_reader :elements
|
9
|
-
protected :elements
|
10
|
-
|
11
|
-
# Utility method to instantiate a Vector
|
12
|
-
#
|
13
|
-
# @param [Array] *array
|
14
|
-
#
|
15
|
-
# @return [Vector]
|
16
|
-
#
|
17
|
-
# @api public
|
18
|
-
def self.[](*array)
|
19
|
-
new(array)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Instantiate a Vector
|
23
|
-
#
|
24
|
-
# @param [Array] array
|
25
|
-
#
|
26
|
-
# @return [undefined]
|
27
|
-
#
|
28
|
-
# @api public
|
29
|
-
def initialize(array = [])
|
30
|
-
@elements = Array(array)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Return element at index.
|
34
|
-
#
|
35
|
-
# @param [Integer] indx
|
36
|
-
# index of an element
|
37
|
-
#
|
38
|
-
# @return [Object]
|
39
|
-
# a value of an element
|
40
|
-
#
|
41
|
-
# @api public
|
42
|
-
def [](indx)
|
43
|
-
elements[indx]
|
44
|
-
end
|
45
|
-
alias at []
|
46
|
-
alias element []
|
47
|
-
|
48
|
-
# Set a value of the element for the given index.
|
49
|
-
#
|
50
|
-
# @param [Integer] indx
|
51
|
-
# an index of an element
|
52
|
-
#
|
53
|
-
# @param [Object] value
|
54
|
-
# a value to be set
|
55
|
-
#
|
56
|
-
# @return [Object]
|
57
|
-
#
|
58
|
-
# @api public
|
59
|
-
def []=(indx, value)
|
60
|
-
elements[indx] = value
|
61
|
-
end
|
62
|
-
alias set_element []=
|
63
|
-
|
64
|
-
# Iterate over each element in the vector
|
65
|
-
#
|
66
|
-
# @example
|
67
|
-
# vec = Vector[1,2,3]
|
68
|
-
# vec.each { |element| ... }
|
69
|
-
#
|
70
|
-
# @return [self]
|
71
|
-
#
|
72
|
-
# @api public
|
73
|
-
def each
|
74
|
-
return to_enum unless block_given?
|
75
|
-
to_ary.each { |element| yield element }
|
76
|
-
self
|
77
|
-
end
|
78
|
-
|
79
|
-
# Convert to array
|
80
|
-
#
|
81
|
-
# @return [Array]
|
82
|
-
#
|
83
|
-
# @api public
|
84
|
-
def to_ary
|
85
|
-
@elements
|
86
|
-
end
|
87
|
-
|
88
|
-
# Check if there are not elements.
|
89
|
-
#
|
90
|
-
# @return [Boolean]
|
91
|
-
#
|
92
|
-
# @api public
|
93
|
-
def empty?
|
94
|
-
to_ary.empty?
|
95
|
-
end
|
96
|
-
|
97
|
-
# Check number of elements.
|
98
|
-
#
|
99
|
-
# @return [Integer]
|
100
|
-
#
|
101
|
-
# @api public
|
102
|
-
def size
|
103
|
-
to_ary.size
|
104
|
-
end
|
105
|
-
alias :length :size
|
106
|
-
|
107
|
-
# Return the vector elements in an array.
|
108
|
-
#
|
109
|
-
# @return [Array]
|
110
|
-
#
|
111
|
-
# @api public
|
112
|
-
def to_a
|
113
|
-
to_ary.dup
|
114
|
-
end
|
115
|
-
end # Vector
|
116
|
-
end # TTY
|
data/spec/tty/logger/log_spec.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'timecop'
|
5
|
-
|
6
|
-
describe TTY::Logger, '#log' do
|
7
|
-
let(:output) { StringIO.new }
|
8
|
-
let(:message) { 'text' }
|
9
|
-
let(:namespace) { 'tty::'}
|
10
|
-
let(:options) { {output: output, namespace: namespace} }
|
11
|
-
let(:object) { described_class.new(options) }
|
12
|
-
|
13
|
-
subject { object.log(message) }
|
14
|
-
|
15
|
-
before { Timecop.freeze }
|
16
|
-
|
17
|
-
after { Timecop.return }
|
18
|
-
|
19
|
-
it 'logs message to output' do
|
20
|
-
subject
|
21
|
-
expect(output.string).to eq("#{object.timestamp} - #{message}")
|
22
|
-
end
|
23
|
-
end
|