chekku 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: