takeltau 0.34.9
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/LICENSE +674 -0
- data/README.md +235 -0
- data/bin/tau +6 -0
- data/lib/Thorfile +3 -0
- data/lib/takeltau.rb +257 -0
- data/lib/takeltau/bit/check/cli.rb +23 -0
- data/lib/takeltau/bit/check/workspace.rb +37 -0
- data/lib/takeltau/bit/cli.rb +18 -0
- data/lib/takeltau/bit/clipboard/cli.rb +73 -0
- data/lib/takeltau/bit/clipboard/copy.rb +142 -0
- data/lib/takeltau/bit/clipboard/lib.rb +143 -0
- data/lib/takeltau/bit/clipboard/paste.rb +60 -0
- data/lib/takeltau/bit/clipboard/pull.rb +37 -0
- data/lib/takeltau/bit/clipboard/push.rb +37 -0
- data/lib/takeltau/bit/require/cli.rb +57 -0
- data/lib/takeltau/bit/require/export.rb +34 -0
- data/lib/takeltau/bit/require/import.rb +133 -0
- data/lib/takeltau/bit/require/lib.rb +19 -0
- data/lib/takeltau/bit/scope/add.rb +55 -0
- data/lib/takeltau/bit/scope/cli.rb +74 -0
- data/lib/takeltau/bit/scope/list.rb +41 -0
- data/lib/takeltau/bit/scope/new.rb +44 -0
- data/lib/takeltau/bit/scope/ssh.rb +13 -0
- data/lib/takeltau/completion/cli.rb +24 -0
- data/lib/takeltau/default.yml +95 -0
- data/lib/takeltau/docker/check/cli.rb +23 -0
- data/lib/takeltau/docker/check/daemon.rb +27 -0
- data/lib/takeltau/docker/cli.rb +15 -0
- data/lib/takeltau/docker/container/check/cli.rb +57 -0
- data/lib/takeltau/docker/container/check/existing.rb +32 -0
- data/lib/takeltau/docker/container/check/network.rb +32 -0
- data/lib/takeltau/docker/container/check/orphaned.rb +32 -0
- data/lib/takeltau/docker/container/clean.rb +40 -0
- data/lib/takeltau/docker/container/cli.rb +118 -0
- data/lib/takeltau/docker/container/command.rb +38 -0
- data/lib/takeltau/docker/container/daemon.rb +17 -0
- data/lib/takeltau/docker/container/lib.rb +181 -0
- data/lib/takeltau/docker/container/login.rb +58 -0
- data/lib/takeltau/docker/container/prune.rb +31 -0
- data/lib/takeltau/docker/image/cli.rb +39 -0
- data/lib/takeltau/docker/image/tag/check.rb +42 -0
- data/lib/takeltau/docker/image/tag/cli.rb +68 -0
- data/lib/takeltau/docker/image/tag/latest.rb +24 -0
- data/lib/takeltau/docker/image/tag/list.rb +19 -0
- data/lib/takeltau/docker/image/update.rb +27 -0
- data/lib/takeltau/git/check/bit.rb +26 -0
- data/lib/takeltau/git/check/clean.rb +46 -0
- data/lib/takeltau/git/check/cli.rb +49 -0
- data/lib/takeltau/git/check/workspace.rb +34 -0
- data/lib/takeltau/git/cli.rb +9 -0
- data/lib/takeltau/info/cli.rb +12 -0
- data/lib/takeltau/info/project/cli.rb +69 -0
- data/lib/takeltau/info/status/bar.rb +112 -0
- data/lib/takeltau/info/status/cli.rb +107 -0
- data/lib/takeltau/info/status/git.rb +47 -0
- data/lib/takeltau/info/status/gopass.rb +37 -0
- data/lib/takeltau/info/status/gpg.rb +39 -0
- data/lib/takeltau/info/status/lib.rb +46 -0
- data/lib/takeltau/info/status/ssh.rb +46 -0
- data/lib/takeltau/init/cli.rb +12 -0
- data/lib/takeltau/init/lib.rb +86 -0
- data/lib/takeltau/init/packer/cli.rb +82 -0
- data/lib/takeltau/init/packer/docker.rb +64 -0
- data/lib/takeltau/init/packer/templates/ansiblelint.tt +3 -0
- data/lib/takeltau/init/packer/templates/bitrequireyml.tt +13 -0
- data/lib/takeltau/init/packer/templates/groupvarsprojectyml.tt +2 -0
- data/lib/takeltau/init/packer/templates/playbooksiteyml.tt +6 -0
- data/lib/takeltau/init/packer/templates/projectyml.tt +19 -0
- data/lib/takeltau/init/takelage/cli.rb +70 -0
- data/lib/takeltau/init/takelage/rake.rb +61 -0
- data/lib/takeltau/init/takelage/templates/bitrequireyml.tt +5 -0
- data/lib/takeltau/init/takelage/templates/projectyml.tt +3 -0
- data/lib/takeltau/init/templates/Rakefile.tt +3 -0
- data/lib/takeltau/init/templates/gitignore.tt +16 -0
- data/lib/takeltau/lib/config.rb +130 -0
- data/lib/takeltau/lib/logging.rb +49 -0
- data/lib/takeltau/lib/project.rb +72 -0
- data/lib/takeltau/lib/subcmd.rb +18 -0
- data/lib/takeltau/lib/system.rb +194 -0
- data/lib/takeltau/mutagen/check/cli.rb +40 -0
- data/lib/takeltau/mutagen/check/daemon.rb +76 -0
- data/lib/takeltau/mutagen/cli.rb +12 -0
- data/lib/takeltau/mutagen/socket/check.rb +33 -0
- data/lib/takeltau/mutagen/socket/cli.rb +103 -0
- data/lib/takeltau/mutagen/socket/create.rb +47 -0
- data/lib/takeltau/mutagen/socket/list.rb +33 -0
- data/lib/takeltau/mutagen/socket/terminate.rb +32 -0
- data/lib/takeltau/mutagen/socket/tidy.rb +21 -0
- data/lib/takeltau/self/cli.rb +43 -0
- data/lib/takeltau/self/config/cli.rb +82 -0
- data/lib/takeltau/self/list.rb +35 -0
- data/lib/takeltau/version +1 -0
- metadata +319 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# takeltau config module
|
|
4
|
+
module ConfigModule
|
|
5
|
+
# takeltau config class.
|
|
6
|
+
class TakeltauConfig
|
|
7
|
+
include Singleton
|
|
8
|
+
include LoggingModule
|
|
9
|
+
include SystemModule
|
|
10
|
+
|
|
11
|
+
attr_accessor :active, :default, :home, :project
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@active = {}
|
|
15
|
+
@default = {}
|
|
16
|
+
@home = {}
|
|
17
|
+
@project = {}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Initialze config
|
|
22
|
+
# rubocop:disable Metrics/AbcSize
|
|
23
|
+
def initialize_config
|
|
24
|
+
project_root_dir = _get_project_root_dir
|
|
25
|
+
|
|
26
|
+
log.debug "takelage version: #{Takeltau::VERSION}"
|
|
27
|
+
log.debug "Current working directory: #{Dir.pwd}"
|
|
28
|
+
log.debug "Project root directory: #{project_root_dir}" unless project_root_dir.empty?
|
|
29
|
+
|
|
30
|
+
TakeltauConfig.instance.default = _config_read_default project_root_dir
|
|
31
|
+
TakeltauConfig.instance.home = _config_read_home
|
|
32
|
+
TakeltauConfig.instance.project = _config_read_project project_root_dir
|
|
33
|
+
TakeltauConfig.instance.active = _config_merge_active
|
|
34
|
+
end
|
|
35
|
+
# rubocop:enable Metrics/AbcSize
|
|
36
|
+
|
|
37
|
+
# @return [Object] global singleton config
|
|
38
|
+
def config
|
|
39
|
+
TakeltauConfig.instance
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @return [Boolean] check if config keys are configured
|
|
43
|
+
def configured?(config_keys)
|
|
44
|
+
@configured = true
|
|
45
|
+
config_keys.each do |config_key|
|
|
46
|
+
next unless _check_key_defined? config_key
|
|
47
|
+
next unless _check_key_set? config_key
|
|
48
|
+
end
|
|
49
|
+
@configured
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
# Check if config key is defined.
|
|
55
|
+
def _check_key_defined?(config_key)
|
|
56
|
+
return true if TakeltauConfig.instance.active.key? config_key
|
|
57
|
+
|
|
58
|
+
log.error "Undefined config key. Please configure \"#{config_key}\""
|
|
59
|
+
@configured = false
|
|
60
|
+
false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Check if config key is nil or empty.
|
|
64
|
+
def _check_key_set?(config_key)
|
|
65
|
+
takel_config_key = TakeltauConfig.instance.active[config_key]
|
|
66
|
+
return true unless takel_config_key.nil? || takel_config_key.empty?
|
|
67
|
+
|
|
68
|
+
if config_key == 'project_root_dir'
|
|
69
|
+
log.error 'Please create a "Rakefile" in the project root directory'
|
|
70
|
+
else
|
|
71
|
+
log.error "Missing config key. Please configure \"#{config_key}\""
|
|
72
|
+
end
|
|
73
|
+
@configured = false
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Read default config file in lib.
|
|
78
|
+
def _config_read_default(project_root_dir)
|
|
79
|
+
default_file = File.expand_path("#{File.dirname(__FILE__)}/../default.yml")
|
|
80
|
+
|
|
81
|
+
return { project_root_dir: project_root_dir } unless File.exist? default_file
|
|
82
|
+
|
|
83
|
+
default_yaml = read_yaml_file(default_file) || {}
|
|
84
|
+
|
|
85
|
+
default_yaml['project_root_dir'] = project_root_dir
|
|
86
|
+
|
|
87
|
+
default_yaml.sort.to_h
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Read custom config file in $HOME.
|
|
91
|
+
def _config_read_home
|
|
92
|
+
home_file = "#{Dir.home}/.takelage.yml"
|
|
93
|
+
|
|
94
|
+
return {} unless File.exist? home_file
|
|
95
|
+
|
|
96
|
+
(read_yaml_file(home_file) || {}).sort.to_h
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Read custom config file in project root.
|
|
100
|
+
def _config_read_project(project_root_dir)
|
|
101
|
+
project_file = "#{project_root_dir}/takelage.yml"
|
|
102
|
+
|
|
103
|
+
return {} unless File.exist? project_file
|
|
104
|
+
|
|
105
|
+
(read_yaml_file(project_file) || {}).sort.to_h
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Merge active config.
|
|
109
|
+
def _config_merge_active
|
|
110
|
+
# make a clone or else we'll change the original hash
|
|
111
|
+
default = TakeltauConfig.instance.default.clone
|
|
112
|
+
home = TakeltauConfig.instance.home.clone
|
|
113
|
+
project = TakeltauConfig.instance.project.clone
|
|
114
|
+
|
|
115
|
+
# merge default and home and project to active
|
|
116
|
+
# project wins against home wins against default
|
|
117
|
+
project_over_home = home.merge!(project)
|
|
118
|
+
default.merge!(project_over_home).sort.to_h
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Get project root directory.
|
|
122
|
+
# @return [String] project root directory
|
|
123
|
+
def _get_project_root_dir
|
|
124
|
+
_rakefile, path = Rake.application.find_rakefile_location
|
|
125
|
+
return path unless path.nil?
|
|
126
|
+
|
|
127
|
+
log.debug 'No "Rakefile" found. Cannot determine project root directory.'
|
|
128
|
+
''
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# takeltau logging module
|
|
4
|
+
module LoggingModule
|
|
5
|
+
# takeltau logger
|
|
6
|
+
class TakeltauLogger
|
|
7
|
+
include Singleton
|
|
8
|
+
|
|
9
|
+
attr_accessor :logger
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@logger = Logger.new($stdout)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Initialize logger with loglevel.
|
|
17
|
+
def initialize_logging(loglevel)
|
|
18
|
+
TakeltauLogger.instance.logger.formatter = _logging_get_log_format
|
|
19
|
+
log_level_in_use = _logging_get_log_level loglevel
|
|
20
|
+
TakeltauLogger.instance.logger.level = log_level_in_use
|
|
21
|
+
TakeltauLogger.instance.logger.debug "Using loglevel #{log_level_in_use}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [Object] global singleton logger
|
|
25
|
+
def log
|
|
26
|
+
TakeltauLogger.instance.logger
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# Get log format.
|
|
32
|
+
def _logging_get_log_format
|
|
33
|
+
proc do |severity, _datetime, _progname, msg|
|
|
34
|
+
"[#{severity}] #{msg}\n"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Get log level.
|
|
39
|
+
def _logging_get_log_level(loglevel)
|
|
40
|
+
if %w[FATAL ERROR WARN INFO DEBUG].include? loglevel
|
|
41
|
+
loglevel
|
|
42
|
+
else
|
|
43
|
+
TakeltauLogger.instance.logger.error 'The parameter "loglevel"' \
|
|
44
|
+
' must be one of FATAL, ERROR, WARN, INFO, DEBUG'
|
|
45
|
+
TakeltauLogger.instance.logger.info 'Using loglevel INFO'
|
|
46
|
+
Logger::INFO
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# takeltau project module
|
|
4
|
+
module ProjectModule
|
|
5
|
+
# takeltau config class.
|
|
6
|
+
class TakeltauProject
|
|
7
|
+
include Singleton
|
|
8
|
+
include LoggingModule
|
|
9
|
+
include SystemModule
|
|
10
|
+
include ConfigModule
|
|
11
|
+
|
|
12
|
+
attr_accessor :active, :private, :main, :dir
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
@active = {}
|
|
16
|
+
@private = {}
|
|
17
|
+
@main = {}
|
|
18
|
+
@dir = {}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Initialze project
|
|
23
|
+
def initialize_project
|
|
24
|
+
TakeltauProject.instance.main = _project_read_main
|
|
25
|
+
TakeltauProject.instance.private = _project_read_private
|
|
26
|
+
TakeltauProject.instance.active = _project_merge_active
|
|
27
|
+
TakeltauProject.instance.dir =
|
|
28
|
+
TakeltauProject.instance.config.active['project_root_dir']
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @return [Object] global singleton project
|
|
32
|
+
def project
|
|
33
|
+
TakeltauProject.instance
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# Read main YAML file.
|
|
39
|
+
def _project_read_main
|
|
40
|
+
dir = TakeltauProject.instance.config.active['project_root_dir']
|
|
41
|
+
main_file = "#{dir}/" \
|
|
42
|
+
"#{TakeltauProject.instance.config.active['info_project_main']}"
|
|
43
|
+
|
|
44
|
+
return {} unless File.exist? main_file
|
|
45
|
+
|
|
46
|
+
(read_yaml_erb_file(main_file) || {}).sort.to_h
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Read private YAML file.
|
|
50
|
+
def _project_read_private
|
|
51
|
+
dir = TakeltauProject.instance.config.active['project_root_dir']
|
|
52
|
+
private_file = "#{dir}/" \
|
|
53
|
+
"#{TakeltauProject.instance.config.active['info_project_private']}"
|
|
54
|
+
|
|
55
|
+
return {} unless File.exist? private_file
|
|
56
|
+
|
|
57
|
+
private_yaml = read_yaml_erb_file(private_file) || {}
|
|
58
|
+
|
|
59
|
+
private_yaml.sort.to_h
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Merge active configuration.
|
|
63
|
+
def _project_merge_active
|
|
64
|
+
# make a clone or else we'll change the original hash
|
|
65
|
+
main = TakeltauProject.instance.main.clone
|
|
66
|
+
private = TakeltauProject.instance.private.clone
|
|
67
|
+
|
|
68
|
+
# merge main and private to active
|
|
69
|
+
# private wins against main
|
|
70
|
+
main.merge!(private).sort.to_h
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Thor with subcommands that work correctly with help
|
|
4
|
+
class SubCommandBase < Thor
|
|
5
|
+
# Set the subcommand banner.
|
|
6
|
+
# rubocop:disable Style/OptionalBooleanParameter
|
|
7
|
+
def self.banner(command, _namespace = nil, _subcommand = false)
|
|
8
|
+
"#{basename} #{subcommand_prefix} #{command.usage}"
|
|
9
|
+
end
|
|
10
|
+
# rubocop:enable Style/OptionalBooleanParameter
|
|
11
|
+
|
|
12
|
+
# Set the subcommand prefix.
|
|
13
|
+
def self.subcommand_prefix
|
|
14
|
+
name.gsub(/.*::/, '')
|
|
15
|
+
.gsub(/^[A-Z]/) { |match| match[0].downcase }
|
|
16
|
+
.gsub(/[A-Z]/) { |match| " #{match[0].downcase}" }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pathname'
|
|
4
|
+
require 'open3'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
|
|
7
|
+
# Interaction with the operating system
|
|
8
|
+
# rubocop:disable Metrics/ModuleLength
|
|
9
|
+
module SystemModule
|
|
10
|
+
# Check if a command is available else log error message
|
|
11
|
+
# @return [Boolean] is the command available?
|
|
12
|
+
def command_available_else_error?(command)
|
|
13
|
+
unless _command_available? command
|
|
14
|
+
log.error "The command \"#{command}\" is not available"
|
|
15
|
+
return false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
command_available command
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Check if a command is available else log warning message
|
|
22
|
+
# @return [Boolean] is the command available?
|
|
23
|
+
def command_available_else_warn?(command)
|
|
24
|
+
unless _command_available? command
|
|
25
|
+
log.warn "The command \"#{command}\" is not available"
|
|
26
|
+
return false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
command_available command
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Convert hash to yaml.
|
|
33
|
+
# @return [String] yaml of hash
|
|
34
|
+
def hash_to_yaml(hash)
|
|
35
|
+
return nil.to_yaml if hash == {}
|
|
36
|
+
|
|
37
|
+
hash.to_yaml({ line_width: -1 })
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Read yaml file.
|
|
41
|
+
# @return [Hash] content of yaml file
|
|
42
|
+
def read_yaml_file(file)
|
|
43
|
+
log.debug "Reading YAML file \"#{file}\""
|
|
44
|
+
return nil unless _file_exists? file
|
|
45
|
+
return nil unless _file_read file
|
|
46
|
+
return nil unless _parse_yaml file, @content_file
|
|
47
|
+
|
|
48
|
+
@content
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Read yaml file with erb templates.
|
|
52
|
+
# @return [Hash] content of yaml file
|
|
53
|
+
def read_yaml_erb_file(file)
|
|
54
|
+
log.debug "Reading YAML ERB file \"#{file}\""
|
|
55
|
+
return nil unless _file_exists? file
|
|
56
|
+
return nil unless _file_read file
|
|
57
|
+
return nil unless _parse_erb file, @content_file
|
|
58
|
+
return nil unless _parse_yaml file, @content_yaml
|
|
59
|
+
|
|
60
|
+
@content
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Remove directory tree.
|
|
64
|
+
def rm_fr(directory)
|
|
65
|
+
unless File.directory? directory
|
|
66
|
+
log.error "Cannot remove non-existing directory \"#{directory}\""
|
|
67
|
+
return
|
|
68
|
+
end
|
|
69
|
+
log.debug "Removing directory \"#{directory}\" recursively"
|
|
70
|
+
Pathname.new(directory).rmtree
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Run a command and return the standard output.
|
|
74
|
+
# @return [String] stdout of command
|
|
75
|
+
def run(command)
|
|
76
|
+
log.debug "Running command \"#{command}\""
|
|
77
|
+
stdout_str, stderr_str, status = Open3.capture3 command
|
|
78
|
+
log.debug "Command \"#{command}\" has stdout:\n\"\"\"\n#{stdout_str}\"\"\""
|
|
79
|
+
log.debug "Command \"#{command}\" has stderr:\n\"\"\"\n#{stderr_str}\"\"\""
|
|
80
|
+
log.debug "Command \"#{command}\" has exit status: \"#{status.exitstatus}\""
|
|
81
|
+
stdout_str
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Run a command and return the standard output
|
|
85
|
+
# the standard error and the exit status
|
|
86
|
+
# @return [[String, String, Integer]] array of
|
|
87
|
+
# stdout, stderr, exitstatus of command
|
|
88
|
+
def run_and_capture(command)
|
|
89
|
+
log.debug "Running amd capturing command \"#{command}\""
|
|
90
|
+
stdout_str, stderr_str, status = Open3.capture3 command
|
|
91
|
+
log.debug "Command \"#{command}\" has stdout:\n\"\"\"\n#{stdout_str}\"\"\""
|
|
92
|
+
log.debug "Command \"#{command}\" has stderr:\n\"\"\"\n#{stderr_str}\"\"\""
|
|
93
|
+
log.debug "Command \"#{command}\" has exit status: \"#{status.exitstatus}\""
|
|
94
|
+
[stdout_str, stderr_str, status.exitstatus]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Use Kernel#exec to replace the ruby process with a command.
|
|
98
|
+
def run_and_exit(command)
|
|
99
|
+
log.debug "Running command \"#{command}\" and exiting afterwards"
|
|
100
|
+
exec command
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Use Kernel#fork and Kernel#exec to run a command as a background process.
|
|
104
|
+
def run_and_fork(command)
|
|
105
|
+
log.debug "Running command \"#{command}\" as a background process"
|
|
106
|
+
job = fork do
|
|
107
|
+
exec command
|
|
108
|
+
end
|
|
109
|
+
Process.detach(job)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Run a command and return the result.
|
|
113
|
+
# @return [Boolean] success of command run
|
|
114
|
+
def try(command)
|
|
115
|
+
log.debug "Running command \"#{command}\""
|
|
116
|
+
stdout_str, stderr_str, status = Open3.capture3 command
|
|
117
|
+
log.debug "Command \"#{command}\" has stdout:\n\"\"\"\n#{stdout_str}\"\"\""
|
|
118
|
+
log.debug "Command \"#{command}\" has stderr:\n\"\"\"\n#{stderr_str}\"\"\""
|
|
119
|
+
log.debug "Command \"#{command}\" has exit status: \"#{status.exitstatus}\""
|
|
120
|
+
status
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
private
|
|
124
|
+
|
|
125
|
+
# Check if command is available
|
|
126
|
+
def _command_available?(command)
|
|
127
|
+
return true if instance_variable_get("@command_available_#{command}")
|
|
128
|
+
|
|
129
|
+
log.debug "Check if the command \"#{command}\" is available"
|
|
130
|
+
status = try "which #{command}"
|
|
131
|
+
return false unless status.exitstatus.zero?
|
|
132
|
+
|
|
133
|
+
true
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Command is available
|
|
137
|
+
def command_available(command)
|
|
138
|
+
log.debug "The command \"#{command}\" is available"
|
|
139
|
+
instance_variable_set("@command_available_#{command}", true)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Check if file exists.
|
|
143
|
+
def _file_exists?(file)
|
|
144
|
+
unless File.exist? File.expand_path(file)
|
|
145
|
+
log.debug "File \"#{file}\" doesn't exist"
|
|
146
|
+
return false
|
|
147
|
+
end
|
|
148
|
+
true
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Read yaml file.
|
|
152
|
+
def _file_read(file)
|
|
153
|
+
begin
|
|
154
|
+
@content_file = File.read File.expand_path(file)
|
|
155
|
+
rescue SystemCallError
|
|
156
|
+
log.debug "Unable to read file \"#{file}\""
|
|
157
|
+
return false
|
|
158
|
+
end
|
|
159
|
+
true
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Parse erb file.
|
|
163
|
+
def _parse_erb(file, content_erb)
|
|
164
|
+
begin
|
|
165
|
+
@content_yaml = ERB.new(content_erb).result
|
|
166
|
+
rescue StandardError => e
|
|
167
|
+
log.debug e.class
|
|
168
|
+
log.debug "Invalid ERB in YAML file \"#{file}\". " \
|
|
169
|
+
"#{e.class}: \"#{e.message}\""
|
|
170
|
+
return false
|
|
171
|
+
end
|
|
172
|
+
true
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Parse yaml file.
|
|
176
|
+
def _parse_yaml(file, content_yaml)
|
|
177
|
+
begin
|
|
178
|
+
@content = YAML.safe_load content_yaml
|
|
179
|
+
rescue Psych::SyntaxError
|
|
180
|
+
log.debug "Invalid YAML file \"#{file}\""
|
|
181
|
+
log.debug "Try: yamllint #{file}"
|
|
182
|
+
return false
|
|
183
|
+
end
|
|
184
|
+
true
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Pluralize a verb in relation to a number
|
|
188
|
+
def pluralize(number, singular, plural)
|
|
189
|
+
return singular if number == 1
|
|
190
|
+
|
|
191
|
+
plural
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
# rubocop:enable Metrics/ModuleLength
|