mux_tf 0.1.2

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.
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuxTf
4
+ module TerraformHelpers
5
+ include PiotrbCliUtils::ShellHelpers
6
+
7
+ def tf_force_unlock(id:)
8
+ run_terraform(tf_prepare_command(['force-unlock', '-force', id], need_auth: true))
9
+ end
10
+
11
+ def tf_apply(filename: nil, targets: [])
12
+ args = []
13
+ args << filename if filename
14
+ if targets && !targets.empty?
15
+ targets.each do |target|
16
+ args << "-target=#{target}"
17
+ end
18
+ end
19
+
20
+ cmd = tf_prepare_command(['apply', *args], need_auth: true)
21
+ run_terraform(cmd)
22
+ end
23
+
24
+ def tf_validate
25
+ cmd = tf_prepare_command(['validate', '-json'], need_auth: true)
26
+ capture_terraform(cmd, json: true)
27
+ end
28
+
29
+ def tf_init(input: nil, upgrade: nil, color: true, &block)
30
+ args = []
31
+ args << "-input=#{input.inspect}" unless input.nil?
32
+ args << '-upgrade' unless upgrade.nil?
33
+ args << '-no-color' unless color
34
+
35
+ cmd = tf_prepare_command(['init', *args], need_auth: true)
36
+ stream_or_run_terraform(cmd, &block)
37
+ end
38
+
39
+ def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, &block)
40
+ args = []
41
+ args += ['-out', out]
42
+ args << "-input=#{input.inspect}" unless input.nil?
43
+ args << '-compact-warnings' if compact_warnings
44
+ args << '-no-color' unless color
45
+ args << '-detailed-exitcode' if detailed_exitcode
46
+
47
+ cmd = tf_prepare_command(['plan', *args], need_auth: true)
48
+ stream_or_run_terraform(cmd, &block)
49
+ end
50
+
51
+ def tf_show(file, json: false)
52
+ if json
53
+ args = ['show', '-json', file]
54
+ cmd = tf_prepare_command(args, need_auth: true)
55
+ capture_terraform(cmd, json: true)
56
+ else
57
+ args = ['show', file]
58
+ cmd = tf_prepare_command(args, need_auth: true)
59
+ run_terraform(cmd)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def tf_prepare_command(args, need_auth:)
66
+ if ENV['MUX_TF_AUTH_WRAPPER'] && need_auth
67
+ words = Shellwords.shellsplit(ENV['MUX_TF_AUTH_WRAPPER'])
68
+ [*words, 'terraform', *args]
69
+ else
70
+ ['terraform', *args]
71
+ end
72
+ end
73
+
74
+ def stream_or_run_terraform(args, &block)
75
+ if block_given?
76
+ stream_terraform(args, &block)
77
+ else
78
+ run_terraform(args)
79
+ end
80
+ end
81
+
82
+ # return_status: false, echo_command: true, quiet: false, indent: 0
83
+ def run_terraform(args, **_options)
84
+ status = run_shell(args, return_status: true, echo_command: true, quiet: false)
85
+ OpenStruct.new({
86
+ status: status,
87
+ success?: status == 0
88
+ })
89
+ end
90
+
91
+ def stream_terraform(args, &block)
92
+ status = run_with_each_line(args, &block)
93
+ # status is a Process::Status
94
+ OpenStruct.new({
95
+ status: status.exitstatus,
96
+ success?: status.exitstatus == 0
97
+ })
98
+ end
99
+
100
+ # error: true, echo_command: true, indent: 0, raise_on_error: false, detailed_result: false
101
+ def capture_terraform(args, json: nil)
102
+ result = capture_shell(args, error: true, echo_command: false, raise_on_error: false, detailed_result: true)
103
+ parsed_output = JSON.parse(result.output) if json
104
+ OpenStruct.new({
105
+ status: result.status,
106
+ success?: result.status == 0,
107
+ output: result.output,
108
+ parsed_output: parsed_output
109
+ })
110
+ rescue JSON::ParserError => e
111
+ fail_with "Execution Failed! - #{result.inspect}"
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shellwords'
4
+
5
+ module MuxTf
6
+ module Tmux
7
+ class << self
8
+ def session_running?(name)
9
+ tmux("has-session -t #{name.inspect} 2>/dev/null", raise_on_error: false)
10
+ end
11
+
12
+ def kill_session(name)
13
+ tmux(%(kill-session -t #{name.inspect}))
14
+ end
15
+
16
+ def find_pane(name)
17
+ panes = `tmux list-panes -F "\#{pane_id},\#{pane_title}"`.strip.split("\n").map do |row|
18
+ x = row.split(',')
19
+ return { id: x[0], name: x[1] }
20
+ end
21
+ panes.find { |pane| pane[:name] == name }
22
+ end
23
+
24
+ def new_session(name)
25
+ tmux %(new-session -s #{name.inspect} -d)
26
+ end
27
+
28
+ def select_pane(name)
29
+ tmux %(select-pane -T #{name.inspect})
30
+ end
31
+
32
+ def set_hook(hook_name, cmd)
33
+ tmux %(set-hook #{hook_name.inspect} #{cmd.inspect})
34
+ end
35
+
36
+ def set(var, value)
37
+ tmux %(set #{var.inspect} #{value.inspect})
38
+ end
39
+
40
+ def tile!
41
+ tmux 'select-layout tiled'
42
+ end
43
+
44
+ def attach(name, cc: false)
45
+ tmux %(#{cc && '-CC' || ''} attach -t #{name.inspect}), raise_on_error: false
46
+ end
47
+
48
+ def kill_pane(pane_id)
49
+ tmux %(kill-pane -t #{pane_id.inspect})
50
+ end
51
+
52
+ def send_keys(cmd, enter: false)
53
+ tmux %(send-keys #{cmd.inspect})
54
+ tmux %(send-keys Enter) if enter
55
+ end
56
+
57
+ def split_window(mode, target_pane, cwd: nil, cmd: nil)
58
+ case mode
59
+ when :horizontal
60
+ mode_part = '-h'
61
+ when :vertical
62
+ mode_part = '-v'
63
+ else
64
+ raise ArgumentError, "invalid mode: #{mode.inspect}"
65
+ end
66
+
67
+ parts = [
68
+ 'split-window',
69
+ cwd && "-c #{cwd}",
70
+ mode_part,
71
+ "-t #{target_pane.inspect}",
72
+ cmd&.inspect
73
+ ].compact
74
+ tmux parts.join(' ')
75
+ end
76
+
77
+ private
78
+
79
+ def tmux_bin
80
+ @tmux_bin ||= `which tmux`.strip
81
+ end
82
+
83
+ def tmux(cmd, raise_on_error: true, mode: :system)
84
+ case mode
85
+ when :system
86
+ # puts " => tmux #{cmd}"
87
+ system("#{tmux_bin} #{cmd}")
88
+ unless $CHILD_STATUS.success?
89
+ if raise_on_error
90
+ fail_with("`tmux #{cmd}' failed with code: #{$CHILD_STATUS.exitstatus}")
91
+ end
92
+
93
+ return false
94
+ end
95
+ true
96
+ when :exec
97
+ exec tmux_bin, *Shellwords.shellwords(cmd)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuxTf
4
+ VERSION = '0.1.2'
5
+ end
data/mux_tf.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/mux_tf/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'mux_tf'
7
+ spec.version = MuxTf::VERSION
8
+ spec.authors = ['Piotr Banasik']
9
+ spec.email = ['piotr@jane.app']
10
+
11
+ spec.summary = 'Terraform Multiplexing Scripts'
12
+ # spec.description = 'TODO: Write a longer description or delete this line.'
13
+ spec.homepage = 'https://github.com/piotrb/mux_tf'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
16
+
17
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = spec.homepage
21
+ # spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_dependency 'activesupport'
33
+ spec.add_dependency 'dotenv'
34
+ spec.add_dependency 'paint'
35
+ spec.add_dependency 'pastel'
36
+ spec.add_dependency 'piotrb_cli_utils', '~> 0.1.0'
37
+ spec.add_dependency 'stateful_parser', '~> 0.1.1'
38
+ spec.add_dependency 'tty-prompt'
39
+ spec.add_dependency 'tty-table'
40
+ end
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mux_tf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Banasik
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-05-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: paint
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pastel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: piotrb_cli_utils
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.1.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.1.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: stateful_parser
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.1.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.1.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: tty-prompt
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: tty-table
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description:
126
+ email:
127
+ - piotr@jane.app
128
+ executables:
129
+ - tf_current
130
+ - tf_mux
131
+ - tf_plan_summary
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - ".gitignore"
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - exe/tf_current
141
+ - exe/tf_mux
142
+ - exe/tf_plan_summary
143
+ - lib/mux_tf.rb
144
+ - lib/mux_tf/cli.rb
145
+ - lib/mux_tf/cli/current.rb
146
+ - lib/mux_tf/cli/mux.rb
147
+ - lib/mux_tf/cli/plan_summary.rb
148
+ - lib/mux_tf/plan_formatter.rb
149
+ - lib/mux_tf/terraform_helpers.rb
150
+ - lib/mux_tf/tmux.rb
151
+ - lib/mux_tf/version.rb
152
+ - mux_tf.gemspec
153
+ homepage: https://github.com/piotrb/mux_tf
154
+ licenses:
155
+ - MIT
156
+ metadata:
157
+ homepage_uri: https://github.com/piotrb/mux_tf
158
+ source_code_uri: https://github.com/piotrb/mux_tf
159
+ post_install_message:
160
+ rdoc_options: []
161
+ require_paths:
162
+ - lib
163
+ required_ruby_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: 2.3.0
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ requirements: []
174
+ rubygems_version: 3.1.3
175
+ signing_key:
176
+ specification_version: 4
177
+ summary: Terraform Multiplexing Scripts
178
+ test_files: []