cliver 0.0.1

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.
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ echo -e "\033[0;36mRuby Appraiser: running\033[0m"
3
+ bundle exec ruby-appraiser --mode=staged reek rubocop
4
+ result_code=$?
5
+ if [ $result_code -gt "0" ]; then
6
+ echo -en "\033[0;31m" # RED
7
+ echo "[✘] Ruby Appraiser found newly-created defects and "
8
+ echo " has blocked your commit."
9
+ echo " Fix the defects and commit again."
10
+ echo " To bypass, commit again with --no-verify."
11
+ echo -en "\033[0m" # RESET
12
+ exit $result_code
13
+ else
14
+ echo -en "\033[0;32m" # GREEN
15
+ echo "[✔] Ruby Appraiser ok"
16
+ echo -en "\033[0m" #RESET
17
+ fi
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ source 'https://rubygems.org'
3
+
4
+ # Specify your gem's dependencies in cliver.gemspec
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ryan Biesemeyer
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,45 @@
1
+ # Cliver
2
+
3
+ Sometimes Ruby apps shell out to command-line executables, but there is no
4
+ standard way to ensure those underlying dependencies are met. Users usually
5
+ find out via a nasty stack-trace and whatever wasn't captured on stderr.
6
+
7
+ `Cliver` is a simple gem that provides an easy way to make assertions about
8
+ command-line dependencies. Under the covers, it uses [rubygems/requirements][]
9
+ so it supports the version requirements you're used to providing in your
10
+ gemspec.
11
+
12
+ ## Usage
13
+
14
+ ```ruby
15
+ Cliver.assert('subl') # no version requirements
16
+ Cliver.assert('bzip2', '~> 1.0.6') # one version requirement
17
+ Cliver.assert('racc', '>= 1.0', '< 1.4.9') # many version requirements
18
+ ```
19
+
20
+ If the executable can't be found on your path at all, a
21
+ `Cliver::Assertion::DependencyNotFound` exception is raised; if the version
22
+ reached does not meet the requirements, a `Cliver::Assertion::VersionMismatch`
23
+ exception is raised.
24
+
25
+ ## Advanced Usage:
26
+
27
+ Some programs don't provide nice 'version 1.2.3' strings in their `--version`
28
+ output; `Cliver` lets you provide your own matcher, whose first group is the
29
+ string version.
30
+
31
+ ```ruby
32
+ Cliver.assert('python', '~> 1.7', version_matcher: /Python ([0-9.]+)/)
33
+ ```
34
+
35
+ Other programs don't provide a standard `--version`; `Cliver` allows you to
36
+ provide your own arg:
37
+
38
+ ```ruby
39
+ Cliver.assert('janky', '~> 10.1.alpha', version_arg: '--release-version')
40
+ ```
41
+
42
+ It obeys all the same rules as `Gem::Requirement`, including pre-release
43
+ semantics.
44
+
45
+ [rubygems/requirements]: https://github.com/rubygems/rubygems/blob/master/lib/rubygems/requirement.rb
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = FileList['spec/**/*_spec.rb']
7
+ spec.verbose = true
8
+ end
data/cliver.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cliver/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cliver'
8
+ spec.version = Cliver::VERSION
9
+ spec.authors = ['Ryan Biesemeyer']
10
+ spec.email = ['ryan@yaauie.com']
11
+ spec.description = 'Assertions for command-line dependencies'
12
+ spec.summary = 'Cross-platform version constraints for cli tools'
13
+ spec.homepage = 'https://www.github.com/yaauie/cliver'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($RS)
17
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec'
24
+ spec.add_development_dependency 'ruby-appraiser-reek'
25
+ spec.add_development_dependency 'ruby-appraiser-rubocop'
26
+ end
data/lib/cliver.rb ADDED
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ require 'cliver/version'
3
+ require 'cliver/assertion'
4
+
5
+ module Cliver
6
+ # See Cliver::Assertion#assert
7
+ def self.assert(*args, &block)
8
+ Assertion.assert!(*args, &block)
9
+ end
10
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ require 'open3'
3
+ require 'rubygems/requirement'
4
+
5
+ module Cliver
6
+ # The core of Cliver, Assertion is responsible for detecting the
7
+ # installed version of a binary and determining if it meets the requirements
8
+ class Assertion
9
+ VersionMismatch = Class.new(ArgumentError)
10
+ DependencyNotFound = Class.new(ArgumentError)
11
+
12
+ EXECUTABLE_PATTERN = /\A[a-z][a-zA-Z0-9\-_]*\z/.freeze
13
+
14
+ # Creates a new instance with the args and calls #assert.
15
+ # @see #assert
16
+ def self.assert!(*args)
17
+ new(*args).assert!
18
+ end
19
+
20
+ # @overload initialize(executable, *requirements, options = {})
21
+ # @param executable [String]
22
+ # @param requirements [Array<String>, String] splat of strings
23
+ # whose elements follow the pattern
24
+ # [<operator>] <version>
25
+ # Where <operator> is optional (default '='') and in the set
26
+ # '=', '!=', '>', '<', '>=', '<=', or '~>'
27
+ # And <version> is dot-separated integers with optional
28
+ # alphanumeric pre-release suffix
29
+ # @see Gem::Requirement::new
30
+ # @param options [Hash<Symbol,Object>]
31
+ # @options options [#match] :version_matcher
32
+ # @options options [String] :version_arg
33
+ def initialize(executable, *args)
34
+ options = args.last.kind_of?(Hash) ? args.pop : {}
35
+ raise ArgumentError, 'executable' unless executable[EXECUTABLE_PATTERN]
36
+
37
+ @executable = executable.dup.freeze
38
+ @requirement = Gem::Requirement.new(args)
39
+ @version_arg = options.fetch(:version_arg, '--version')
40
+ @version_matcher = options.fetch(:version_matcher,
41
+ /version ([0-9][.0-9a-z]+)/i)
42
+ end
43
+
44
+ # @raise [VersionMismatch] if installed version does not match requirement
45
+ # @raise [DependencyNotFound] if no installed version on your path
46
+ def assert!
47
+ version = installed_version
48
+ version || raise(DependencyNotFound, "#{@executable} missing.")
49
+ unless @requirement.satisfied_by?(version)
50
+ raise VersionMismatch,
51
+ "got #{version}, expected #{@requirement}"
52
+ end
53
+ end
54
+
55
+ # @private
56
+ def installed_version
57
+ command = "which #{@executable} && #{@executable} #{@version_arg}"
58
+ command_out, _ = Open3.capture2e(command)
59
+ match = @version_matcher.match(command_out)
60
+ match && Gem::Version.new(match[1])
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Cliver
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+ require 'cliver/assertion'
3
+
4
+ describe Cliver::Assertion do
5
+ let(:mismatch_exception) { Cliver::Assertion::VersionMismatch }
6
+ let(:missing_exception) { Cliver::Assertion::DependencyNotFound }
7
+ let(:requirements) { ['6.8'] }
8
+ let(:executable) { 'fubar' }
9
+ let(:assertion) { Cliver::Assertion.new(executable, *requirements) }
10
+
11
+ context 'when dependency found' do
12
+ before(:each) { assertion.stub(:installed_version) { version } }
13
+
14
+ # sampling of requirements; actual implementation
15
+ # is supplied by rubygems/requirement and well-tested there.
16
+ context '~>' do
17
+ let(:requirements) { ['~> 6.8'] }
18
+ context 'when version matches exactly' do
19
+ let(:version) { Gem::Version.new('6.8') }
20
+ it 'should not raise' do
21
+ expect { assertion.assert! }.to_not raise_exception
22
+ end
23
+ end
24
+ context 'when major matches, and minor too low' do
25
+ let(:version) { Gem::Version.new('6.7') }
26
+ it 'should raise' do
27
+ expect { assertion.assert! }.to raise_exception mismatch_exception
28
+ end
29
+ end
30
+ context 'when major matches, and minor bumped' do
31
+ let(:version) { Gem::Version.new('6.13') }
32
+ it 'should not raise' do
33
+ expect { assertion.assert! }.to_not raise_exception
34
+ end
35
+ end
36
+ context 'when major too high' do
37
+ let(:version) { Gem::Version.new('7.0') }
38
+ it 'should raise' do
39
+ expect { assertion.assert! }.to raise_exception mismatch_exception
40
+ end
41
+ end
42
+ context 'patch version present' do
43
+ let(:version) { Gem::Version.new('6.8.1') }
44
+ it 'should not raise' do
45
+ expect { assertion.assert! }.to_not raise_exception
46
+ end
47
+ end
48
+ context 'pre-release of version that matches' do
49
+ let(:version) { Gem::Version.new('6.8.a') }
50
+ it 'should raise' do
51
+ version.should be_prerelease
52
+ expect { assertion.assert! }.to raise_exception mismatch_exception
53
+ end
54
+ end
55
+ end
56
+
57
+ context 'multi [>=,<]' do
58
+ let(:requirements) { ['>= 1.1.4', '< 3.1'] }
59
+ context 'matches both' do
60
+ let(:version) { Gem::Version.new('2.0') }
61
+ it 'should not raise' do
62
+ expect { assertion.assert! }.to_not raise_exception
63
+ end
64
+ end
65
+ context 'fails one' do
66
+ let(:version) { Gem::Version.new('3.1') }
67
+ it 'should raise' do
68
+ expect { assertion.assert! }.to raise_exception mismatch_exception
69
+ end
70
+ end
71
+ end
72
+
73
+ context 'none' do
74
+ let(:requirements) { [] }
75
+ let(:version) { Gem::Version.new('3.1') }
76
+ it 'should not raise' do
77
+ expect { assertion.assert! }.to_not raise_exception
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'when dependency not found' do
83
+ before(:each) { assertion.stub(:installed_version) { nil } }
84
+
85
+ it 'should raise' do
86
+ expect { assertion.assert! }.to raise_exception missing_exception
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ require 'cliver'
3
+
4
+ describe Cliver do
5
+ it { should respond_to :assert }
6
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cliver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Biesemeyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: ruby-appraiser-reek
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: ruby-appraiser-rubocop
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Assertions for command-line dependencies
95
+ email:
96
+ - ryan@yaauie.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .githooks/pre-commit/ruby-appraiser
102
+ - .gitignore
103
+ - Gemfile
104
+ - LICENSE.txt
105
+ - README.md
106
+ - Rakefile
107
+ - cliver.gemspec
108
+ - lib/cliver.rb
109
+ - lib/cliver/assertion.rb
110
+ - lib/cliver/version.rb
111
+ - spec/cliver/assertion_spec.rb
112
+ - spec/cliver_spec.rb
113
+ homepage: https://www.github.com/yaauie/cliver
114
+ licenses:
115
+ - MIT
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.24
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Cross-platform version constraints for cli tools
138
+ test_files:
139
+ - spec/cliver/assertion_spec.rb
140
+ - spec/cliver_spec.rb
141
+ has_rdoc: