minarai 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +41 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +21 -0
- data/Rakefile +6 -0
- data/bin/minarai +5 -0
- data/examples/recipe_directory.yml +8 -0
- data/examples/recipe_erb.yml.erb +13 -0
- data/examples/recipe_file.yml +11 -0
- data/examples/recipe_git.yml +9 -0
- data/examples/recipe_homebrew.yml +6 -0
- data/examples/recipe_homebrew_cask.yml +6 -0
- data/examples/recipe_link.yml +4 -0
- data/examples/recipe_url_get.yml +4 -0
- data/examples/recipe_variable.yml +4 -0
- data/lib/minarai.rb +6 -0
- data/lib/minarai/action_builder.rb +47 -0
- data/lib/minarai/actions/base.rb +87 -0
- data/lib/minarai/actions/directory.rb +51 -0
- data/lib/minarai/actions/file.rb +85 -0
- data/lib/minarai/actions/git.rb +36 -0
- data/lib/minarai/actions/homebrew.rb +35 -0
- data/lib/minarai/actions/homebrew_cask.rb +35 -0
- data/lib/minarai/actions/link.rb +53 -0
- data/lib/minarai/actions/unknown.rb +26 -0
- data/lib/minarai/actions/url_get.rb +38 -0
- data/lib/minarai/command.rb +47 -0
- data/lib/minarai/errors/attribute_validation_error.rb +17 -0
- data/lib/minarai/errors/base.rb +6 -0
- data/lib/minarai/errors/invalid_action_type_error.rb +15 -0
- data/lib/minarai/errors/missing_recipe_path_error.rb +11 -0
- data/lib/minarai/loaders/base.rb +75 -0
- data/lib/minarai/loaders/recipe_loader.rb +39 -0
- data/lib/minarai/loaders/variable_loader.rb +14 -0
- data/lib/minarai/logger.rb +69 -0
- data/lib/minarai/recipe.rb +28 -0
- data/lib/minarai/runner.rb +22 -0
- data/lib/minarai/variable.rb +19 -0
- data/lib/minarai/version.rb +3 -0
- data/lib/validator/required_validator.rb +7 -0
- data/lib/validator/type_validator.rb +13 -0
- data/minarai.gemspec +30 -0
- data/spec/minarai/unit/action/base_spec.rb +26 -0
- data/spec/minarai/unit/action_builder_spec.rb +21 -0
- data/spec/minarai/unit/logger_spec.rb +18 -0
- data/spec/minarai/unit/variable_spec.rb +11 -0
- data/spec/spec_helper.rb +5 -0
- metadata +240 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'minarai/actions/base'
|
2
|
+
|
3
|
+
module Minarai
|
4
|
+
module Actions
|
5
|
+
class Git < Base
|
6
|
+
attribute :repository, required: true
|
7
|
+
attribute :destination, required: true
|
8
|
+
|
9
|
+
def run
|
10
|
+
clone
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def complete?
|
16
|
+
has_git? && existed?
|
17
|
+
end
|
18
|
+
|
19
|
+
def clone
|
20
|
+
run_command("git clone #{repository} #{destination}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def existed?
|
24
|
+
check_specific_command(:check_file_is_directory, destination)
|
25
|
+
end
|
26
|
+
|
27
|
+
def has_git?
|
28
|
+
check_command 'which git'
|
29
|
+
end
|
30
|
+
|
31
|
+
def name
|
32
|
+
super || "clone #{repository} to #{destination}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'minarai/actions/base'
|
2
|
+
|
3
|
+
module Minarai
|
4
|
+
module Actions
|
5
|
+
class Homebrew < Base
|
6
|
+
attribute :item, required: true
|
7
|
+
|
8
|
+
def run
|
9
|
+
install
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def install
|
15
|
+
run_specific_command(:install_package, item)
|
16
|
+
end
|
17
|
+
|
18
|
+
def complete?
|
19
|
+
has_homebrew? && installed?
|
20
|
+
end
|
21
|
+
|
22
|
+
def installed?
|
23
|
+
check_specific_command(:check_package_is_installed, item)
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_homebrew?
|
27
|
+
check_command 'which brew'
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
super || "brew install #{item}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'minarai/actions/base'
|
2
|
+
|
3
|
+
module Minarai
|
4
|
+
module Actions
|
5
|
+
class HomebrewCask < Base
|
6
|
+
attribute :item, required: true
|
7
|
+
|
8
|
+
def run
|
9
|
+
install
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def install
|
15
|
+
run_command "brew cask install #{item}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def complete?
|
19
|
+
has_homebrew? && installed?
|
20
|
+
end
|
21
|
+
|
22
|
+
def installed?
|
23
|
+
check_command "/usr/local/bin/brew cask list -1 | grep -E '^#{item}$'"
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_homebrew?
|
27
|
+
check_command 'which brew-cask'
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
super || "brew cask install #{item}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'minarai/actions/base'
|
2
|
+
|
3
|
+
module Minarai
|
4
|
+
module Actions
|
5
|
+
class Link < Base
|
6
|
+
attribute :destination, required: true, type: String
|
7
|
+
attribute :source, required: true, type: String
|
8
|
+
|
9
|
+
def call
|
10
|
+
abort_with_runtime_error unless runnable?
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
link
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def link
|
21
|
+
run_specific_command(:link_file_to, destination, source)
|
22
|
+
end
|
23
|
+
|
24
|
+
def complete?
|
25
|
+
existed_file?
|
26
|
+
end
|
27
|
+
|
28
|
+
def readable_source?
|
29
|
+
!source.nil? && ::File.readable?(source)
|
30
|
+
end
|
31
|
+
|
32
|
+
def runnable?
|
33
|
+
readable_source?
|
34
|
+
end
|
35
|
+
|
36
|
+
def abort_with_runtime_error
|
37
|
+
Minarai::Logger.errorr(runtime_error) and abort
|
38
|
+
end
|
39
|
+
|
40
|
+
def runtime_error
|
41
|
+
Minarai::Errors::AttributeValidationError.new('source', 'is not readable file', name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def existed_file?
|
45
|
+
check_specific_command(:check_file_is_linked_to, destination, source)
|
46
|
+
end
|
47
|
+
|
48
|
+
def name
|
49
|
+
super || "create symlink #{repository} to #{destination}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'minarai/actions/base'
|
2
|
+
require 'minarai/errors/invalid_action_type_error'
|
3
|
+
|
4
|
+
module Minarai
|
5
|
+
module Actions
|
6
|
+
class Unknown < Base
|
7
|
+
def run
|
8
|
+
# override
|
9
|
+
end
|
10
|
+
|
11
|
+
def error_messages
|
12
|
+
[Minarai::Errors::InvalidActionTypeError.new(name)]
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def complete?
|
18
|
+
# override
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
super || 'unknow action'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'minarai/actions/base'
|
2
|
+
|
3
|
+
module Minarai
|
4
|
+
module Actions
|
5
|
+
class UrlGet < Base
|
6
|
+
attribute :source, required: true, type: String
|
7
|
+
attribute :destination, required: true, type: String
|
8
|
+
|
9
|
+
def run
|
10
|
+
url_get
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def url_get
|
16
|
+
run_command("curl -o #{destination} #{source}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def complete?
|
20
|
+
has_url_get? && existed?
|
21
|
+
end
|
22
|
+
|
23
|
+
def existed?
|
24
|
+
%i(check_file_is_file check_file_is_directory).any? do |command|
|
25
|
+
check_specific_command(command, destination)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_url_get?
|
30
|
+
check_command 'which curl'
|
31
|
+
end
|
32
|
+
|
33
|
+
def name
|
34
|
+
super || "url-get form #{source} to #{destination}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'slop'
|
2
|
+
require 'minarai/loaders/recipe_loader'
|
3
|
+
require 'minarai/errors/missing_recipe_path_error.rb'
|
4
|
+
require 'minarai/logger'
|
5
|
+
|
6
|
+
module Minarai
|
7
|
+
class Command
|
8
|
+
def initialize(args)
|
9
|
+
@args = args
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
Minarai::Logger.info 'Minarai starting...'
|
14
|
+
abort_with_error_message unless recipe.valid?
|
15
|
+
recipe.runner.run
|
16
|
+
Minarai::Logger.info 'Minarai finish'
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def abort_with_error_message
|
22
|
+
Minarai::Logger.error(recipe.errors) and abort
|
23
|
+
end
|
24
|
+
|
25
|
+
def recipe
|
26
|
+
@recipe ||= Minarai::Loaders::RecipeLoader.new(recipe_path, variable_path: variable_path).load
|
27
|
+
end
|
28
|
+
|
29
|
+
def recipe_path
|
30
|
+
slop_options.arguments[0] || (Minarai::Logger.error(recipe_missing_error) and abort)
|
31
|
+
end
|
32
|
+
|
33
|
+
def recipe_missing_error
|
34
|
+
Minarai::Errors::MissingRecipePathError.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def variable_path
|
38
|
+
slop_options[:variables]
|
39
|
+
end
|
40
|
+
|
41
|
+
def slop_options
|
42
|
+
@slop_options ||= Slop.parse(@args, suppress_errors: true) do |option|
|
43
|
+
option.string '-v', '--variables', 'variable file for erb recipe file'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'minarai/errors/base'
|
2
|
+
|
3
|
+
module Minarai
|
4
|
+
module Errors
|
5
|
+
class AttributeValidationError < Base
|
6
|
+
def initialize(attribute, error_message, name)
|
7
|
+
@attribute = attribute
|
8
|
+
@error_message = error_message
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"`#{@attribute}` #{@error_message} @ #{@name}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'pathname'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Minarai
|
6
|
+
module Loaders
|
7
|
+
class Base
|
8
|
+
def initialize(path)
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
|
12
|
+
def load
|
13
|
+
case
|
14
|
+
when !existed_file?
|
15
|
+
raise "Does not exist file: #{pathname}"
|
16
|
+
when yml_file?
|
17
|
+
load_yaml_file
|
18
|
+
when erb_file?
|
19
|
+
load_erb_file
|
20
|
+
else
|
21
|
+
raise 'inalid extname error'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def binding_for_erb
|
28
|
+
TOPLEVEL_BINDING
|
29
|
+
end
|
30
|
+
|
31
|
+
def loaded_class
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_yaml_file
|
36
|
+
loaded_class.new(load_file_from_yaml)
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_erb_file
|
40
|
+
self.class.new(parsed_erb_file.path).load
|
41
|
+
end
|
42
|
+
|
43
|
+
def parsed_erb
|
44
|
+
ERB.new(pathname.read).result(binding_for_erb)
|
45
|
+
end
|
46
|
+
|
47
|
+
def parsed_erb_file
|
48
|
+
@parsed_erb_file ||= Tempfile.open(['', '.yml']) do |tmp|
|
49
|
+
tmp.puts parsed_erb
|
50
|
+
tmp
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def existed_file?
|
55
|
+
pathname.exist?
|
56
|
+
end
|
57
|
+
|
58
|
+
def yml_file?
|
59
|
+
%w(.yml yaml).include?(pathname.extname)
|
60
|
+
end
|
61
|
+
|
62
|
+
def erb_file?
|
63
|
+
pathname.extname == '.erb'
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_file_from_yaml
|
67
|
+
YAML.load_file(pathname)
|
68
|
+
end
|
69
|
+
|
70
|
+
def pathname
|
71
|
+
@pathname ||= Pathname.new(@path)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'minarai/recipe'
|
2
|
+
require 'minarai/loaders/base'
|
3
|
+
require 'minarai/loaders/variable_loader'
|
4
|
+
require 'minarai/variable'
|
5
|
+
|
6
|
+
module Minarai
|
7
|
+
module Loaders
|
8
|
+
class RecipeLoader < Base
|
9
|
+
def initialize(path, variable_path: nil)
|
10
|
+
super(path)
|
11
|
+
@variable_path = variable_path
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def loaded_class
|
17
|
+
Minarai::Recipe
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_variable_path?
|
21
|
+
!@variable_path.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def binding_for_erb
|
25
|
+
variables.to_mash.binding
|
26
|
+
end
|
27
|
+
|
28
|
+
def variables
|
29
|
+
@variables ||= begin
|
30
|
+
if has_variable_path?
|
31
|
+
Minarai::Loaders::VariableLoader.new(@variable_path).load
|
32
|
+
else
|
33
|
+
Minarai::Variable.new({})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|