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.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +235 -0
  4. data/bin/tau +6 -0
  5. data/lib/Thorfile +3 -0
  6. data/lib/takeltau.rb +257 -0
  7. data/lib/takeltau/bit/check/cli.rb +23 -0
  8. data/lib/takeltau/bit/check/workspace.rb +37 -0
  9. data/lib/takeltau/bit/cli.rb +18 -0
  10. data/lib/takeltau/bit/clipboard/cli.rb +73 -0
  11. data/lib/takeltau/bit/clipboard/copy.rb +142 -0
  12. data/lib/takeltau/bit/clipboard/lib.rb +143 -0
  13. data/lib/takeltau/bit/clipboard/paste.rb +60 -0
  14. data/lib/takeltau/bit/clipboard/pull.rb +37 -0
  15. data/lib/takeltau/bit/clipboard/push.rb +37 -0
  16. data/lib/takeltau/bit/require/cli.rb +57 -0
  17. data/lib/takeltau/bit/require/export.rb +34 -0
  18. data/lib/takeltau/bit/require/import.rb +133 -0
  19. data/lib/takeltau/bit/require/lib.rb +19 -0
  20. data/lib/takeltau/bit/scope/add.rb +55 -0
  21. data/lib/takeltau/bit/scope/cli.rb +74 -0
  22. data/lib/takeltau/bit/scope/list.rb +41 -0
  23. data/lib/takeltau/bit/scope/new.rb +44 -0
  24. data/lib/takeltau/bit/scope/ssh.rb +13 -0
  25. data/lib/takeltau/completion/cli.rb +24 -0
  26. data/lib/takeltau/default.yml +95 -0
  27. data/lib/takeltau/docker/check/cli.rb +23 -0
  28. data/lib/takeltau/docker/check/daemon.rb +27 -0
  29. data/lib/takeltau/docker/cli.rb +15 -0
  30. data/lib/takeltau/docker/container/check/cli.rb +57 -0
  31. data/lib/takeltau/docker/container/check/existing.rb +32 -0
  32. data/lib/takeltau/docker/container/check/network.rb +32 -0
  33. data/lib/takeltau/docker/container/check/orphaned.rb +32 -0
  34. data/lib/takeltau/docker/container/clean.rb +40 -0
  35. data/lib/takeltau/docker/container/cli.rb +118 -0
  36. data/lib/takeltau/docker/container/command.rb +38 -0
  37. data/lib/takeltau/docker/container/daemon.rb +17 -0
  38. data/lib/takeltau/docker/container/lib.rb +181 -0
  39. data/lib/takeltau/docker/container/login.rb +58 -0
  40. data/lib/takeltau/docker/container/prune.rb +31 -0
  41. data/lib/takeltau/docker/image/cli.rb +39 -0
  42. data/lib/takeltau/docker/image/tag/check.rb +42 -0
  43. data/lib/takeltau/docker/image/tag/cli.rb +68 -0
  44. data/lib/takeltau/docker/image/tag/latest.rb +24 -0
  45. data/lib/takeltau/docker/image/tag/list.rb +19 -0
  46. data/lib/takeltau/docker/image/update.rb +27 -0
  47. data/lib/takeltau/git/check/bit.rb +26 -0
  48. data/lib/takeltau/git/check/clean.rb +46 -0
  49. data/lib/takeltau/git/check/cli.rb +49 -0
  50. data/lib/takeltau/git/check/workspace.rb +34 -0
  51. data/lib/takeltau/git/cli.rb +9 -0
  52. data/lib/takeltau/info/cli.rb +12 -0
  53. data/lib/takeltau/info/project/cli.rb +69 -0
  54. data/lib/takeltau/info/status/bar.rb +112 -0
  55. data/lib/takeltau/info/status/cli.rb +107 -0
  56. data/lib/takeltau/info/status/git.rb +47 -0
  57. data/lib/takeltau/info/status/gopass.rb +37 -0
  58. data/lib/takeltau/info/status/gpg.rb +39 -0
  59. data/lib/takeltau/info/status/lib.rb +46 -0
  60. data/lib/takeltau/info/status/ssh.rb +46 -0
  61. data/lib/takeltau/init/cli.rb +12 -0
  62. data/lib/takeltau/init/lib.rb +86 -0
  63. data/lib/takeltau/init/packer/cli.rb +82 -0
  64. data/lib/takeltau/init/packer/docker.rb +64 -0
  65. data/lib/takeltau/init/packer/templates/ansiblelint.tt +3 -0
  66. data/lib/takeltau/init/packer/templates/bitrequireyml.tt +13 -0
  67. data/lib/takeltau/init/packer/templates/groupvarsprojectyml.tt +2 -0
  68. data/lib/takeltau/init/packer/templates/playbooksiteyml.tt +6 -0
  69. data/lib/takeltau/init/packer/templates/projectyml.tt +19 -0
  70. data/lib/takeltau/init/takelage/cli.rb +70 -0
  71. data/lib/takeltau/init/takelage/rake.rb +61 -0
  72. data/lib/takeltau/init/takelage/templates/bitrequireyml.tt +5 -0
  73. data/lib/takeltau/init/takelage/templates/projectyml.tt +3 -0
  74. data/lib/takeltau/init/templates/Rakefile.tt +3 -0
  75. data/lib/takeltau/init/templates/gitignore.tt +16 -0
  76. data/lib/takeltau/lib/config.rb +130 -0
  77. data/lib/takeltau/lib/logging.rb +49 -0
  78. data/lib/takeltau/lib/project.rb +72 -0
  79. data/lib/takeltau/lib/subcmd.rb +18 -0
  80. data/lib/takeltau/lib/system.rb +194 -0
  81. data/lib/takeltau/mutagen/check/cli.rb +40 -0
  82. data/lib/takeltau/mutagen/check/daemon.rb +76 -0
  83. data/lib/takeltau/mutagen/cli.rb +12 -0
  84. data/lib/takeltau/mutagen/socket/check.rb +33 -0
  85. data/lib/takeltau/mutagen/socket/cli.rb +103 -0
  86. data/lib/takeltau/mutagen/socket/create.rb +47 -0
  87. data/lib/takeltau/mutagen/socket/list.rb +33 -0
  88. data/lib/takeltau/mutagen/socket/terminate.rb +32 -0
  89. data/lib/takeltau/mutagen/socket/tidy.rb +21 -0
  90. data/lib/takeltau/self/cli.rb +43 -0
  91. data/lib/takeltau/self/config/cli.rb +82 -0
  92. data/lib/takeltau/self/list.rb +35 -0
  93. data/lib/takeltau/version +1 -0
  94. metadata +319 -0
@@ -0,0 +1,5 @@
1
+ ---
2
+ scopes:
3
+ takelage.rake:
4
+ - name: rake/meta
5
+ - name: rake/rubylint
@@ -0,0 +1,3 @@
1
+ ---
2
+ name: <%= name %>
3
+ version: 0.1.0
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ load 'rake/meta/Rakefile'
@@ -0,0 +1,16 @@
1
+ .DS_Store
2
+ .idea
3
+ *.iml
4
+ *.iso
5
+ packer/images
6
+ packer/packer_cache
7
+ __pycache__/
8
+ *.pyc
9
+ .pytest_cache
10
+ pytestdebug.log
11
+ *.retry
12
+ takelage.log
13
+ takelage.yml
14
+ .vagrant
15
+ vault-password-file
16
+ *.vdi
@@ -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