takeltau 0.34.9

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