tty-which 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a5024ca88ff5be5656247e0686827463e5f0cea3
4
+ data.tar.gz: ee9eaeddd82f8eede886aabb018842b87b5335fe
5
+ SHA512:
6
+ metadata.gz: 96fcfce47fd6a6ec990e74c21266890efc9ef0355dadd2b054a5ed23207902a095c2ae470869a26a726a124262b1065e7c4019baeb741082a7f70aac240217e5
7
+ data.tar.gz: bf4197d3b5588999005df72b4e9232ff523d75a04fc764fc70eb5d46121f8364dc678d5eeeaf254d7fb94914e77290c6c6f63f0a03e0d4bb907dfc1ad39559b4
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --warnings
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ bundler_args: --without yard guard benchmarks
3
+ script: "bundle exec rake ci"
4
+ rvm:
5
+ - 1.9
6
+ - 2.0
7
+ - 2.1
8
+ - 2.2
9
+ - ruby-head
10
+ - rbx-2
11
+ - jruby-19mode
12
+ matrix:
13
+ include:
14
+ - rvm: jruby-head
15
+ allow_failures:
16
+ - rvm: ruby-head
17
+ - rvm: jruby-head
18
+ fast_finish: true
19
+ branches:
20
+ only: master
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake', '~> 10.4.2'
7
+ gem 'rspec', '~> 3.2.0'
8
+ gem 'yard', '~> 0.8.7'
9
+ end
10
+
11
+ group :metrics do
12
+ gem 'coveralls', '~> 0.8.1'
13
+ gem 'simplecov', '~> 0.10.0'
14
+ gem 'yardstick', '~> 0.9.9'
15
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Piotr Murach
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # TTY::Which
2
+ [![Gem Version](https://badge.fury.io/rb/tty-which.svg)][gem]
3
+ [![Build Status](https://secure.travis-ci.org/peter-murach/tty-which.svg?branch=master)][travis]
4
+ [![Code Climate](https://codeclimate.com/github/peter-murach/tty-which/badges/gpa.svg)][codeclimate]
5
+ [![Coverage Status](https://coveralls.io/repos/peter-murach/tty-which/badge.svg?branch=master)][coveralls]
6
+ [![Inline docs](http://inch-ci.org/github/peter-murach/tty-which.svg?branch=master)][inchpages]
7
+
8
+ [gem]: http://badge.fury.io/rb/tty-which
9
+ [travis]: http://travis-ci.org/peter-murach/tty-which
10
+ [codeclimate]: https://codeclimate.com/github/peter-murach/tty-which
11
+ [coveralls]: https://coveralls.io/r/peter-murach/tty-which
12
+ [inchpages]: http://inch-ci.org/github/peter-murach/tty-which
13
+
14
+ > Platform independent implementation of Unix `which` utility that searches for executable file in the path.
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'tty-which'
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install tty-which
29
+
30
+ ## Usage
31
+
32
+ **TTY::Which** exposes `which` method that searches the path for executable file that would be run had the command been invoked.
33
+
34
+ For example, to find location for a single command do:
35
+
36
+ ```ruby
37
+ TTY::Which.which('less') # => '/usr/bin/less'
38
+ TTY::Which.which('git') # => 'C:\Program Files\Git\bin\git'
39
+ ```
40
+
41
+ You can also check an absolute path:
42
+
43
+ ```ruby
44
+ TTY::Which.which('/usr/bin/ruby') # => '/usr/bin/ruby'
45
+ ```
46
+
47
+ ## Contributing
48
+
49
+ 1. Fork it ( https://github.com/peter-murach/tty-which/fork )
50
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
51
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
52
+ 4. Push to the branch (`git push origin my-new-feature`)
53
+ 5. Create a new Pull Request
54
+
55
+ ## Copyright
56
+
57
+ Copyright (c) 2015 Piotr Murach. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+
5
+ FileList['tasks/**/*.rake'].each(&method(:import))
6
+
7
+ desc 'Run all specs'
8
+ task ci: %w[ spec ]
data/lib/tty-which.rb ADDED
@@ -0,0 +1,3 @@
1
+ # coding: utf-8
2
+
3
+ require 'tty/which'
data/lib/tty/which.rb ADDED
@@ -0,0 +1,134 @@
1
+ # coding: utf-8
2
+
3
+ require 'tty/which/version'
4
+
5
+ module TTY
6
+ # A class responsible for finding an executable in the PATH
7
+ module Which
8
+ extend self
9
+ # Find an executable in a platform independent way
10
+ #
11
+ # @param [String] command
12
+ # the command to search for
13
+ #
14
+ # @example
15
+ # which('ruby') # => '/usr/local/bin/ruby'
16
+ # which('/usr/local/bin/ruby') # => '/usr/local/bin/ruby'
17
+ # which('foo') # => nil
18
+ #
19
+ # @return [String, nil]
20
+ # the absolute path to executable if found, `nil` otherwise
21
+ #
22
+ # @api public
23
+ def which(cmd, search_path = nil)
24
+ if path_with_executable_file?(cmd)
25
+ return cmd if executable_file?(cmd)
26
+ extensions.each do |ext|
27
+ exe = File.join(cmd, ext)
28
+ return File.absolute_path(exe) if executable_file?(exe)
29
+ end
30
+ return nil
31
+ end
32
+
33
+ search_path ||= search_paths
34
+ search_path.each do |path|
35
+ if executable_file_with_ext?(cmd)
36
+ exe = File.join(path, cmd)
37
+ return File.absolute_path(exe) if executable_file?(exe)
38
+ end
39
+ extensions.each do |ext|
40
+ exe = File.join(path, "#{cmd}#{ext}")
41
+ return File.absolute_path(exe) if executable_file?(exe)
42
+ end
43
+ end
44
+ nil
45
+ end
46
+
47
+ private
48
+
49
+ # Find default system paths
50
+ #
51
+ # @return [Array[String]]
52
+ # the array of paths to search
53
+ #
54
+ # @api private
55
+ def search_paths
56
+ paths = if ENV['PATH']
57
+ ENV['PATH'].split(File::PATH_SEPARATOR)
58
+ else
59
+ %w(/usr/local/bin /usr/ucb /usr/bin /bin)
60
+ end
61
+ paths.select { |path| Dir.exist?(path) }
62
+ end
63
+
64
+ # All files that contain a '.' in name
65
+ #
66
+ # @example
67
+ # extensions('.exe;cmd;.bat')
68
+ # # => ['.exe','.bat']
69
+ #
70
+ # @param [String] path_ext
71
+ # a string of semicolon separated filename extensions
72
+ #
73
+ # @return [Array[String]]
74
+ # an array with valid file extensions
75
+ #
76
+ # @api private
77
+ def extensions(path_ext = ENV['PATHEXT'])
78
+ return [''] unless path_ext
79
+ path_ext.split(';').select { |part| part.include?('.') }
80
+ end
81
+
82
+ # Determines if filename is an executable file
83
+ #
84
+ # @example Basic usage
85
+ # executable_file?('/usr/bin/less') # => true
86
+ #
87
+ # @example Executable in directory
88
+ # executable_file?('less', '/usr/bin') # => true
89
+ # executable_file?('less', '/usr') # => false
90
+ #
91
+ # @param [String] filename
92
+ # the path to file
93
+ # @param [String] dir
94
+ # the directory within which to search for filename
95
+ #
96
+ # @return [Boolean]
97
+ #
98
+ # @api private
99
+ def executable_file?(filename, dir = nil)
100
+ path = File.join(dir, filename) if dir
101
+ path ||= filename
102
+ File.file?(path) && File.executable?(path)
103
+ end
104
+
105
+ # Check if command itself has extension
106
+ #
107
+ # @param [String] filename
108
+ # the path to file
109
+ #
110
+ # @example
111
+ # executable_file_with_ext?("file.bat") # => true
112
+ #
113
+ # @return [Boolean]
114
+ #
115
+ # @api private
116
+ def executable_file_with_ext?(filename)
117
+ extension = File.extname(filename)
118
+ return false if extension.empty?
119
+ extensions.any? { |ext| extension.casecmp(ext) }
120
+ end
121
+
122
+ # Check if executable file is part of absolute/relative path
123
+ #
124
+ # @param [String] cmd
125
+ # the executable to check
126
+ #
127
+ # @return [Boolean]
128
+ #
129
+ # @api private
130
+ def path_with_executable_file?(cmd)
131
+ File.expand_path(cmd) == cmd
132
+ end
133
+ end # Which
134
+ end # TTY
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ module Which
5
+ VERSION = "0.1.0"
6
+ end # Which
7
+ end # TTY
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+
3
+ if RUBY_VERSION > '1.9' and (ENV['COVERAGE'] || ENV['TRAVIS'])
4
+ require 'simplecov'
5
+ require 'coveralls'
6
+
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov::Formatter::HTMLFormatter,
9
+ Coveralls::SimpleCov::Formatter
10
+ ]
11
+
12
+ SimpleCov.start do
13
+ command_name 'spec'
14
+ add_filter 'spec'
15
+ end
16
+ end
17
+
18
+ require 'tty-which'
19
+
20
+ RSpec.configure do |config|
21
+ config.expect_with :rspec do |expectations|
22
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
23
+ end
24
+
25
+ config.mock_with :rspec do |mocks|
26
+ mocks.verify_partial_doubles = true
27
+ end
28
+
29
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
30
+ config.disable_monkey_patching!
31
+
32
+ # This setting enables warnings. It's recommended, but in some cases may
33
+ # be too noisy due to issues in dependencies.
34
+ config.warnings = true
35
+
36
+ if config.files_to_run.one?
37
+ config.default_formatter = 'doc'
38
+ end
39
+
40
+ config.profile_examples = 2
41
+
42
+ config.order = :random
43
+
44
+ Kernel.srand config.seed
45
+ end
@@ -0,0 +1,117 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Which, '#which' do
4
+
5
+ before { stub_const("Which", described_class) }
6
+
7
+ context "without extension" do
8
+ let(:path) { "/bin:/usr/bin:/usr/local/bin:/opt/local/bin" }
9
+ let(:cmds) { %w(/usr/bin/ls /bin/sh /usr/bin/ruby /usr/local/git/bin/git) }
10
+
11
+ before {
12
+ allow(ENV).to receive(:[]).with('PATHEXT').and_return(nil)
13
+ allow(ENV).to receive(:[]).with('PATH').and_return(path)
14
+ stub_const("File::PATH_SEPARATOR", ':')
15
+ stub_const("File::SEPARATOR", '/')
16
+ allow(Dir).to receive(:exist?) { true }
17
+ }
18
+
19
+ it "handles path with executable file /bin/sh" do
20
+ allow(Which).to receive(:path_with_executable_file?) { true }
21
+ allow(Which).to receive(:executable_file?) { true }
22
+
23
+ expect(Which.which('/bin/sh')).to eq('/bin/sh')
24
+ end
25
+
26
+ it "fails to find path executable" do
27
+ allow(Which).to receive(:path_with_executable_file?) { true }
28
+ allow(Which).to receive(:executable_file?) { false }
29
+
30
+ expect(Which.which('/bin/sh')).to eq(nil)
31
+ end
32
+
33
+ it "searches executable file git" do
34
+ dir_path = "/usr/local/bin"
35
+ cmd = "git"
36
+ expected_path = "#{dir_path}/#{cmd}"
37
+ allow(Which).to receive(:path_with_executable_file?) { false }
38
+ allow(Which).to receive(:executable_file_with_ext?) { false }
39
+
40
+ allow(File).to receive(:join)
41
+ allow(File).to receive(:join).with(dir_path, cmd).and_return(expected_path)
42
+ allow(Which).to receive(:executable_file?) { false }
43
+ allow(Which).to receive(:executable_file?).with(expected_path) { true }
44
+ allow(File).to receive(:absolute_path).with(expected_path).
45
+ and_return(expected_path)
46
+
47
+ expect(Which.which(cmd)).to eq(expected_path)
48
+ end
49
+ end
50
+
51
+ context "with extension" do
52
+ let(:path) { "C:\\Program Files\\Git\\bin;" }
53
+ let(:exts) { ".com;.exe;.bat;.cmd" }
54
+
55
+ before {
56
+ allow(ENV).to receive(:[]).with('PATHEXT').and_return(exts)
57
+ allow(ENV).to receive(:[]).with('PATH').and_return(path)
58
+ stub_const("File::PATH_SEPARATOR", ';')
59
+ stub_const("File::SEPARATOR", '\\')
60
+ allow(Dir).to receive(:exist?) { true }
61
+ }
62
+
63
+ it "handles path with executable file C:\\Program Files\\Git\\bin\\git" do
64
+ allow(Which).to receive(:path_with_executable_file?) { true }
65
+ allow(Which).to receive(:executable_file?).with(any_args) { false }
66
+
67
+ path_with_exe_file = 'C:\Program Files\Git\bin\git'
68
+ expected_path = "#{path_with_exe_file}.exe"
69
+
70
+ allow(File).to receive(:join).with(path_with_exe_file, any_args).
71
+ and_return(path_with_exe_file)
72
+ allow(File).to receive(:join).with(path_with_exe_file, '.exe').
73
+ and_return(expected_path)
74
+ allow(Which).to receive(:executable_file?).with(expected_path) { true }
75
+ allow(File).to receive(:absolute_path).and_return(expected_path)
76
+
77
+ expect(Which.which(path_with_exe_file)).to eq(expected_path)
78
+ end
79
+
80
+ it "searches path for executable git.exe" do
81
+ dir_path = "C:\\Program Files\\Git\\bin"
82
+ cmd = 'git.exe'
83
+ expected_path = "#{dir_path}\\#{cmd}"
84
+ allow(Which).to receive(:path_with_executable_file?) { false }
85
+ allow(Which).to receive(:executable_file_with_ext?).with(cmd) { true }
86
+
87
+ allow(File).to receive(:join).with(dir_path, any_args)
88
+ allow(File).to receive(:join).with(dir_path, cmd).and_return(expected_path)
89
+ allow(Which).to receive(:executable_file?).with(any_args) { false }
90
+ allow(Which).to receive(:executable_file?).with(expected_path) { true }
91
+ allow(File).to receive(:absolute_path).with(expected_path).
92
+ and_return(expected_path)
93
+
94
+ expect(Which.which(cmd)).to eq(expected_path)
95
+ expect(File).to have_received(:absolute_path).with(expected_path)
96
+ end
97
+
98
+ it "searches path for executable git" do
99
+ dir_path = "C:\\Program Files\\Git\\bin"
100
+ cmd = 'git'
101
+ expected_path = "#{dir_path}\\#{cmd}.exe"
102
+ allow(Which).to receive(:path_with_executable_file?) { false }
103
+ allow(Which).to receive(:executable_file_with_ext?).with(cmd) { false }
104
+
105
+ allow(File).to receive(:join).with(dir_path, any_args)
106
+ allow(File).to receive(:join).with(dir_path, "#{cmd}.exe").
107
+ and_return(expected_path)
108
+ allow(Which).to receive(:executable_file?).with(any_args) { false }
109
+ allow(Which).to receive(:executable_file?).with(expected_path) { true }
110
+ allow(File).to receive(:absolute_path).with(expected_path).
111
+ and_return(expected_path)
112
+
113
+ expect(Which.which(cmd)).to eq(expected_path)
114
+ expect(File).to have_received(:absolute_path).with(expected_path)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Load gem inside irb console'
4
+ task :console do
5
+ require 'irb'
6
+ require 'irb/completion'
7
+ require File.join(__FILE__, '../../lib/tty-which')
8
+ ARGV.clear
9
+ IRB.start
10
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Measure code coverage'
4
+ task :coverage do
5
+ begin
6
+ original, ENV['COVERAGE'] = ENV['COVERAGE'], 'true'
7
+ Rake::Task['spec'].invoke
8
+ ensure
9
+ ENV['COVERAGE'] = original
10
+ end
11
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Run all specs'
7
+ RSpec::Core::RakeTask.new(:spec) do |task|
8
+ task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
9
+ end
10
+
11
+ namespace :spec do
12
+ desc 'Run unit specs'
13
+ RSpec::Core::RakeTask.new(:unit) do |task|
14
+ task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
15
+ end
16
+
17
+ desc 'Run integration specs'
18
+ RSpec::Core::RakeTask.new(:integration) do |task|
19
+ task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
20
+ end
21
+ end
22
+
23
+ rescue LoadError
24
+ %w[spec spec:unit spec:integration].each do |name|
25
+ task name do
26
+ $stderr.puts "In order to run #{name}, do `gem install rspec`"
27
+ end
28
+ end
29
+ end
data/tty-which.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tty/which/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tty-which"
8
+ spec.version = TTY::Which::VERSION
9
+ spec.authors = ["Piotr Murach"]
10
+ spec.email = [""]
11
+ spec.summary = %q{Platform independent implementation of Unix which command.}
12
+ spec.description = %q{Platform independent implementation of Unix which command.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tty-which
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Murach
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ description: Platform independent implementation of Unix which command.
28
+ email:
29
+ - ''
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - .rspec
36
+ - .ruby-version
37
+ - .travis.yml
38
+ - Gemfile
39
+ - LICENSE.txt
40
+ - README.md
41
+ - Rakefile
42
+ - lib/tty-which.rb
43
+ - lib/tty/which.rb
44
+ - lib/tty/which/version.rb
45
+ - spec/spec_helper.rb
46
+ - spec/unit/which_spec.rb
47
+ - tasks/console.rake
48
+ - tasks/coverage.rake
49
+ - tasks/spec.rake
50
+ - tty-which.gemspec
51
+ homepage: ''
52
+ licenses:
53
+ - MIT
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 2.0.3
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: Platform independent implementation of Unix which command.
75
+ test_files:
76
+ - spec/spec_helper.rb
77
+ - spec/unit/which_spec.rb
78
+ has_rdoc: