chekku 0.0.5 → 0.1.0

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.
data/README.md CHANGED
@@ -54,6 +54,14 @@ imagemagick:
54
54
  executable: 'convert'
55
55
  ```
56
56
 
57
+ ## Use Definition object in your code
58
+
59
+ Example on how to check a software dependency
60
+
61
+ ```
62
+ definition = Chekku::Definition.new(name: 'mysql', executable: 'mysqld')
63
+ definition.chekku('>= 5.0')
64
+ ```
57
65
 
58
66
  ## Future
59
67
 
@@ -14,6 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.required_ruby_version = '>= 1.9'
15
15
  gem.required_rubygems_version = '>= 1.3.6'
16
16
  gem.add_development_dependency 'rspec', '>= 2.0'
17
+ gem.add_development_dependency 'simplecov'
17
18
  gem.add_dependency 'thor'
18
19
  gem.add_dependency 'rake'
19
20
  gem.files = `git ls-files`.split($/)
@@ -4,6 +4,8 @@ require 'thor/group'
4
4
  require 'chekku/errors'
5
5
 
6
6
  module Chekku
7
+ # Launch the whole process of software dependencies checking
8
+ #
7
9
  class Command
8
10
  if ARGV.first == 'version'
9
11
  puts Chekku::VERSION
@@ -10,6 +10,7 @@ class Chekku::Checker < Thor
10
10
 
11
11
  method_option :chekkufile, type: :string, desc: 'Chekkufile Path', default: 'Chekkufile'
12
12
 
13
+ # Checks the software dependencies based on the chekku files
13
14
  def checks
14
15
  @chekkufile = options[:chekkufile]
15
16
  verify_chekku_file_existence
@@ -1,85 +1,148 @@
1
1
  #encoding: utf-8
2
- class Chekku::Definition
2
+ require_relative 'errors'
3
3
 
4
- attr_accessor :name, :executable, :version_checker, :errors
4
+ # This Definition object has attributes for checking
5
+ # if the software is installed and respect conditions
6
+ #
7
+ # You can use this class in your code to easily embed software checks
8
+ #
9
+ # @example Check a software Dependency
10
+ # definition = Chekku::Definition.new(name: 'mysql', executable: 'mysqld')
11
+ # definition.chekku('>= 5.0', must_run: true)
12
+ #
13
+ # @attr [String] name the Definition name used in the Chekkufile and def.yml file
14
+ # @attr [String] executable the actual software dependency executable name
15
+ module Chekku
16
+ class Definition
5
17
 
6
- def self.load(definitions_hash = {})
7
- [].tap do |definitions|
8
- definitions_hash.each_pair do |name, hash_definition|
9
- definitions << self.new(hash_definition.merge(name: name))
18
+ attr_accessor :name, :executable
19
+
20
+ # Convert a formatted hash to an array of definitions
21
+ #
22
+ # @param [Hash] definitions_hash a valid hash of definitions
23
+ # @return [Array] an Array of Definition
24
+ def self.load(definitions_hash = {})
25
+ [].tap do |definitions|
26
+ definitions_hash.each_pair do |name, hash_definition|
27
+ definitions << self.new(hash_definition.merge(name: name))
28
+ end
10
29
  end
11
30
  end
12
- end
13
31
 
14
- def initialize(attributes = {})
15
- attributes.each do |name, value|
16
- send("#{name}=", value)
32
+ def initialize(attributes = {})
33
+ attributes.each do |name, value|
34
+ send("#{name}=", value)
35
+ end
17
36
  end
18
- @errors = {}
19
- end
20
37
 
21
- def chekku(version = nil, args = {})
22
- raise(DefinitionValidationError, "not installed") unless exists?
23
- validates version, args
24
- "[\033[32m✓\033[0m] #{name}"
25
- end
38
+ # Check if version and other params are valid for current Definition instance and raise errors
39
+ #
40
+ # @param [String] version Version to check in the format '>= 4.0' accepts '~> 3.0'
41
+ # @param [Hash] args Possible checks that must be verified for current Definition
42
+ # @option args [Boolean] must_run Check if the software is running on the host
43
+ # @return [Boolean] true if valid, if not valid errors are raised
44
+ # @raise [DefinitionValidationError] An exception if the params requirements are not met
45
+ # @raise [AppNameNotStringError] if Definition is not correct and executable isn't a string
46
+ # @raise [AppNameNotSaneError] if Definition executable isn't safe (spaces, special chars and so on)
47
+ def chekku!(version = nil, args = {})
48
+ raise(DefinitionValidationError, "not installed") unless exists?
49
+ validates version, args
50
+ end
26
51
 
27
- def exists?
28
- verify_executable! && found?
29
- end
52
+ # Check if version and other params are valid for current Definition instance and return false if errors
53
+ # @param (see #chekku!)
54
+ # @return [Boolean] version and args are valid => true else false
55
+ def chekku(version = nil, args = {})
56
+ chekku!(version, args)
57
+ rescue
58
+ false
59
+ end
30
60
 
31
- def verify_executable!
32
- raise(AppNameNotStringError, 'You need to use strings for app names') unless executable.is_a?(String)
33
- raise(AppNameNotSaneError, "Sorry the app name '#{name}' is not sane") unless sane_executable?
34
- true
35
- end
61
+ # Verify existence of dependency
62
+ #
63
+ # @return [Boolean] corresponding to the existence
64
+ def exists?
65
+ verify_executable! && found?
66
+ end
36
67
 
37
- def found?
38
- system "which #{executable} > /dev/null 2>&1"
39
- end
68
+ # Validates the params provided are the one of the local dependency
69
+ #
70
+ # @param (see #chekku)
71
+ # @return [Boolean] valid?
72
+ def validates(version = nil, args = {})
73
+ raise(DefinitionValidationError, "wrong version: wanted #{version}, got #{installed_version}") unless ( !version || check_version(version))
74
+ raise(DefinitionValidationError, "installed but not running (must_run: true)") unless (!args[:must_run] || is_running?)
75
+ true
76
+ end
40
77
 
41
- def sane_executable?
42
- executable == sanitized_executable
43
- end
78
+ # Verify if the executable of the Definition is sane and correct
79
+ #
80
+ # @return [Boolean] valid?
81
+ def verify_executable!
82
+ raise(AppNameNotStringError, 'You need to use strings for app names') unless executable.is_a?(String)
83
+ raise(AppNameNotSaneError, "Sorry the app name '#{name}' is not sane") unless sane_executable?
84
+ true
85
+ end
44
86
 
45
- def sanitized_executable
46
- executable.gsub /&|"|'|;|\s/, ""
47
- end
87
+ # Actual method which verifies if defined software is present
88
+ #
89
+ # @return [Boolean] found?
90
+ def found?
91
+ system "which #{executable} > /dev/null 2>&1"
92
+ end
48
93
 
49
- def validates(version = nil, args = {})
50
- raise(DefinitionValidationError, "wrong version: wanted #{version}, got #{installed_version}") unless ( !version || check_version(version))
51
- raise(DefinitionValidationError, "installed but not running (must_run: true)") unless (!args[:must_run] || is_running?)
52
- true
53
- end
94
+ # Verify that the executable is harmless for the machine
95
+ #
96
+ # @return [Boolean] sane?
97
+ def sane_executable?
98
+ executable == sanitized_executable
99
+ end
54
100
 
55
- def is_running?
56
- ps_result = `ps aux | grep #{executable}`
57
- ps_result_array = ps_result.split("\n")
58
- ps_result_array.any? do |ps_line|
59
- ps_line.include?(executable) && (executable == 'grep' || !ps_line.include?('grep'))
101
+ # Get the sanitized name of the executable
102
+ #
103
+ # @return [String] sane executable
104
+ def sanitized_executable
105
+ executable.gsub /&|"|'|;|\s/, ""
60
106
  end
61
- end
62
107
 
63
- def check_version(version)
64
- operator, version = version.split(' ')
65
- if version.nil?
66
- version = operator
67
- operator = '=='
108
+ # Verify that current executable is running or not on host
109
+ #
110
+ # @return [Boolean] running?
111
+ def is_running?
112
+ ps_result = `ps aux | grep #{executable}`
113
+ ps_result_array = ps_result.split("\n")
114
+ ps_result_array.any? do |ps_line|
115
+ ps_line.include?(executable) && (executable == 'grep' || !ps_line.include?('grep'))
116
+ end
68
117
  end
69
- if operator == '~>'
70
- installed_version >= Gem::Version.new(version) && installed_version <= Gem::Version.new(version).bump
71
- else
72
- installed_version.send(operator, Gem::Version.new(version))
118
+
119
+ # Verify version
120
+ #
121
+ # @param [String] version current version wanted
122
+ # @return [Boolean] good_version?
123
+ def check_version(version)
124
+ operator, version = version.split(' ')
125
+ if version.nil?
126
+ version = operator
127
+ operator = '=='
128
+ end
129
+ if operator == '~>'
130
+ installed_version >= Gem::Version.new(version) && installed_version <= Gem::Version.new(version).bump
131
+ else
132
+ installed_version.send(operator, Gem::Version.new(version))
133
+ end
73
134
  end
74
- end
75
135
 
76
- def installed_version
77
- version_matches = `#{executable} --version`.scan(/(\d+[\.\d+]*)/).flatten
78
- max_dot_number_version = ''
79
- version_matches.each do |version|
80
- max_dot_number_version = version if version.count('.') > max_dot_number_version.count('.')
136
+ # Get the current installed version on the host
137
+ #
138
+ # @return [String] string representation of version
139
+ def installed_version
140
+ version_matches = `#{executable} --version`.scan(/(\d+[\.\d+]*)/).flatten
141
+ max_dot_number_version = ''
142
+ version_matches.each do |version|
143
+ max_dot_number_version = version if version.count('.') > max_dot_number_version.count('.')
144
+ end
145
+ Gem::Version.new(max_dot_number_version)
81
146
  end
82
- Gem::Version.new(max_dot_number_version)
83
147
  end
84
-
85
148
  end
@@ -6,41 +6,61 @@ class Chekku::Definitions
6
6
 
7
7
  attr_accessor :definitions_service, :dependency_checker
8
8
 
9
- def self.evaluate(file)
10
- new.eval_chekkufile(file)
9
+ # Evaluate the given Chekkufile and check every dependency
10
+ #
11
+ # @param [String] file_path Path to Chekkufile
12
+ def self.evaluate(file_path)
13
+ new.eval_chekkufile(file_path)
11
14
  end
12
15
 
16
+ # Instanciate a new instance and create a DefinitionService
13
17
  def initialize
14
18
  @definitions_service = Chekku::DefinitionsService.new
15
19
  @definitions_service.load_definitions_for @chekkufile
16
20
  end
17
21
 
18
- def eval_chekkufile(file)
19
- instance_eval(read_file(file))
22
+ # Parse the file and evaluate every dependency
23
+ #
24
+ # @param [String] file_path Path to Chekkufile
25
+ # @raise [NoMethodError] Wrong format of Chekkufile
26
+ def eval_chekkufile(file_path)
27
+ instance_eval(read_file(file_path))
20
28
  rescue NoMethodError => e
21
29
  puts "\033[31mERROR: Please verify the syntax of your Chekkufile"
22
30
  end
23
31
 
32
+ # Check against the Definition if depency is valid
33
+ # Actual method written in the Chekkufile
34
+ # It is responsible to output the result
35
+ #
36
+ # @param [String] name Name of the Definition
37
+ # @param [String] version Current version wanted on the host
38
+ # @param [Hash] args for the moment only must_run: true false Indicating if is running or not
24
39
  def check(name, version = nil, args = {})
25
40
  unless version.is_a?(String)
26
41
  args = version || {}
27
42
  version = nil
28
43
  end
29
44
  definition = get_definition! name
30
- puts definition.chekku(version, args)
45
+ puts "[\033[32m✓\033[0m] #{name}" if definition.chekku(version, args)
31
46
  rescue DefinitionsError => e
32
47
  puts "[\033[31m✗\033[0m] #{name}: #{e.message}\n"
33
48
  rescue ChekkuError => e
34
49
  puts "\033[31mERROR: #{e.message}\033[0m\n"
35
50
  end
36
51
 
52
+ # Retrieve the Definition instance from the DefinitionService
53
+ #
54
+ # @param [String] name Definition name
55
+ # @return [Definition] actual definition
56
+ # @raise [DefinitionNotFoundError] if Definition is not found
37
57
  def get_definition!(name)
38
58
  @definitions_service.definition_for(name) ||
39
59
  raise(DefinitionNotFoundError, "#{name} definition not found. Check ~/.chekku/def.yml")
40
60
  end
41
61
 
42
- def read_file(file)
43
- File.open(file, "r") { |f| f.read }
62
+ def read_file(file_path)
63
+ File.open(file_path, "r") { |f| f.read }
44
64
  end
45
65
 
46
66
  end
@@ -4,11 +4,18 @@ class Chekku::DefinitionsService
4
4
 
5
5
  attr_accessor :definitions
6
6
 
7
- def load_definitions_for(file)
8
- @definitions = Chekku::Fetcher.fetch_for_chekkufile file
7
+ # load the Definition list for the needed dependencies
8
+ #
9
+ # @param [String] file_path Path to Chekkufile
10
+ def load_definitions_for(file_path)
11
+ @definitions = Chekku::Fetcher.fetch_for_chekkufile file_path
9
12
  end
10
13
 
11
- def definition_for(dependency)
12
- @definitions.select{ |definition| definition.name == dependency }.first if @definitions
14
+ # Retrieve one Definition from the list
15
+ #
16
+ # @param [String] definition_name The needed Definition name
17
+ # @return [Definition] The needed Definition
18
+ def definition_for(definition_name)
19
+ @definitions.select{ |definition| definition.name == definition_name }.first if @definitions
13
20
  end
14
21
  end
@@ -8,7 +8,11 @@ class Chekku::Fetcher
8
8
 
9
9
  attr_accessor :dependencies
10
10
 
11
- def self.fetch_for_chekkufile(file)
11
+ # Fetch the Definitions from the file
12
+ #
13
+ # @param [String] file_path Path to Chekkufile
14
+ # @return [Array] a list of Definition instances
15
+ def self.fetch_for_chekkufile(file_path)
12
16
  # TODO: Implements server side of the file checker
13
17
  # STUB: Load local file
14
18
  fetcher = new
@@ -1,3 +1,3 @@
1
1
  module Chekku
2
- VERSION = '0.0.5'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  #encoding: utf-8
2
+ require 'spec_helper'
2
3
  require 'chekku/definition'
3
4
  require 'chekku/errors'
4
5
 
@@ -76,14 +77,27 @@ describe Chekku::Definition do
76
77
  end
77
78
  end
78
79
 
80
+ describe '.chekku!' do
81
+ it 'should says ✓ if soft exists' do
82
+ definition.stub(:exists?).and_return(true)
83
+ definition.chekku!.should be_true
84
+ end
85
+
86
+ it 'should says x if soft does not exist' do
87
+ definition.stub(:exists?).and_return(false)
88
+ expect { definition.chekku! }.to raise_error(DefinitionValidationError)
89
+ end
90
+ end
91
+
79
92
  describe '.chekku' do
80
93
  it 'should says ✓ if soft exists' do
81
94
  definition.stub(:exists?).and_return(true)
82
- definition.chekku.should == "[\033[32m✓\033[0m] mysql"
95
+ definition.chekku.should be_true
83
96
  end
97
+
84
98
  it 'should says x if soft does not exist' do
85
99
  definition.stub(:exists?).and_return(false)
86
- expect { definition.chekku }.to raise_error(DefinitionValidationError)
100
+ definition.chekku.should be_false
87
101
  end
88
102
  end
89
103
 
@@ -1,3 +1,4 @@
1
+ require 'spec_helper'
1
2
  require 'chekku/definitions_service'
2
3
  require 'chekku/errors'
3
4
 
@@ -1,4 +1,5 @@
1
1
  #encoding: utf-8
2
+ require 'spec_helper'
2
3
  require 'chekku/definitions'
3
4
  require 'chekku/definitions_service'
4
5
  require 'chekku/errors'
@@ -13,11 +14,13 @@ describe Chekku::Definitions do
13
14
 
14
15
  describe '.get_definition' do
15
16
  it 'should return the definition' do
17
+ Chekku::DefinitionsService.any_instance.stub(:load_definitions_for)
16
18
  definitions.definitions_service.stub(:definition_for).with('mysql').and_return(definition)
17
19
  definitions.get_definition!('mysql').should == definition
18
20
  end
19
21
 
20
22
  it 'should raise an error if not found' do
23
+ Chekku::DefinitionsService.any_instance.stub(:load_definitions_for)
21
24
  definitions.definitions_service.stub(:definition_for).with('mysql').and_return(nil)
22
25
  expect{ definitions.get_definition!('mysql') }.to raise_error(DefinitionNotFoundError)
23
26
  end
@@ -1,3 +1,4 @@
1
+ require 'spec_helper'
1
2
  require 'chekku/fetcher'
2
3
 
3
4
  describe Chekku::Fetcher do
@@ -1,16 +1,3 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
1
+ require 'simplecov'
2
+ SimpleCov.start
3
3
 
4
- require 'chekku'
5
- # Load support files
6
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
7
-
8
- # Load fixtures from the engine
9
- if ActiveSupport::TestCase.method_defined?(:fixture_path=)
10
- ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
11
- end
12
-
13
- RSpec.configure do |config|
14
- config.before :each do
15
- end
16
- end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chekku
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-16 00:00:00.000000000 Z
12
+ date: 2012-10-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: simplecov
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'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: thor
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -121,3 +137,4 @@ test_files:
121
137
  - spec/lib/definitions_spec.rb
122
138
  - spec/lib/fetcher_spec.rb
123
139
  - spec/spec_helper.rb
140
+ has_rdoc: