minarai 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.
- 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
|