smdev 0.3.0 → 0.5.0

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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/smdev/ecs_exec.rb +92 -0
  3. data/lib/smdev.rb +158 -121
  4. metadata +7 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cb7ef8e326aefb0cec817caef086d1079b26404c1cc6d04ebc91c8db5ccf7b5
4
- data.tar.gz: 12b8cc2b5899723602ae6347c31f5cffb9ecf6026ebc39f595d7bc670abe0346
3
+ metadata.gz: 61964b5c32328c5e2265a32622cb85c366a70780eeaab4b95e154577942602b9
4
+ data.tar.gz: 39c56ddd43405021c465494bf439e174681e431146e59a808937f0c6592a2f97
5
5
  SHA512:
6
- metadata.gz: b8e0db249fa4c0f91eee94c4ba0408ee6ea7517a58d6c0b8e91b12f700786ee0a8e504b0fe05bf25b4ba76f7a03b4f5297d755648ae429ee071cc73c221967b7
7
- data.tar.gz: 0d31f663ac690004e11f3a3a05c45f995dc4f7c9cf51e5f193b08e73398dddfc36f5718c4602f3a053ed320a0c4892a82bae2be1a0434edc4e43c7cd68c4b105
6
+ metadata.gz: 54d844cb8292bea2cf364c473809f385bba2375d4bedede0927192c620e33bc685289831b1f7973a17a19d7b8471acfda9cf46de845367b7f2d2ab15ee3994e5
7
+ data.tar.gz: 123be6e3958715b82e1c0ae92c25e9a63f580ad0cbf55f43a2369ee1dbea782fe6d3b7dbb71e551ce4b66ef767ec817097ea0a8d6cd39ade8d3818c14482d13d
@@ -0,0 +1,92 @@
1
+ require 'open3'
2
+
3
+ module Smdev
4
+ module EcsExec
5
+ def self.ssh(options)
6
+ cluster_name = self.cluster_name(options)
7
+ return if cluster_name == nil
8
+ puts "Found cluster #{cluster_name}"
9
+
10
+ service_name = self.service_name(options, cluster_name)
11
+ return if service_name == nil
12
+ puts "Found service #{service_name}"
13
+
14
+ task_arn = self.task_arn(cluster_name, service_name)
15
+ puts "Found first task #{task_arn}"
16
+ command = options[:command]
17
+
18
+ execute_command_cmd = %W[
19
+ aws ecs execute-command
20
+ --cluster #{cluster_name}
21
+ --task #{task_arn}
22
+ --interactive
23
+ --command \"#{command}\"
24
+ ].join(' ')
25
+
26
+ puts "Running \"#{command}\""
27
+ exec(execute_command_cmd)
28
+ end
29
+
30
+ def self.cluster_name(options)
31
+ cluster = options[:cluster]
32
+ command = "aws ecs list-clusters | grep #{cluster}"
33
+ stdout, stderr, status = Open3.capture3(command)
34
+
35
+ if status.success?
36
+ match = stdout.match(/cluster\/([^"]+)/)
37
+ cluster_name = match[1] if match
38
+
39
+ return cluster_name
40
+ else
41
+ if stderr != ""
42
+ puts "Error executing command: #{stderr}"
43
+ else
44
+ puts "Could not find cluster whose name contains \"#{cluster}\""
45
+ end
46
+ end
47
+ end
48
+
49
+ def self.service_name(options, cluster_name)
50
+ service = options[:service]
51
+ command = "aws ecs list-services --cluster #{cluster_name} | grep #{service}"
52
+ stdout, stderr, status = Open3.capture3(command)
53
+
54
+ if status.success?
55
+ match = stdout.match(/#{cluster_name}\/([^"]+)/)
56
+ service_name = match[1] if match
57
+
58
+ return service_name
59
+ else
60
+ if stderr != ""
61
+ puts "Error executing command: #{stderr}"
62
+ else
63
+ puts "Could not find service whose name contains \"#{service}\""
64
+ end
65
+ end
66
+ end
67
+
68
+ def self.task_arn(cluster_name, service_name)
69
+ list_tasks_cmd = "aws ecs list-tasks --cluster #{cluster_name} --service-name #{service_name}"
70
+ stdout, stderr, status = Open3.capture3(list_tasks_cmd)
71
+
72
+ if status.success?
73
+ begin
74
+ tasks = JSON.parse(stdout)
75
+ task_arn = tasks['taskArns'][0]
76
+
77
+ if task_arn.nil? || task_arn.empty?
78
+ puts 'No task ARN found.'
79
+ exit 1
80
+ end
81
+ return task_arn
82
+ rescue JSON::ParserError
83
+ puts 'Error parsing JSON'
84
+ exit 1
85
+ end
86
+ else
87
+ puts "Error executing command: #{stderr}"
88
+ exit 1
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/smdev.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'io/console'
3
3
  require 'octokit'
4
4
  require 'optparse'
5
+ require 'smdev/ecs_exec'
5
6
 
6
7
  module Smdev
7
8
  class CLI
@@ -9,7 +10,10 @@ module Smdev
9
10
  options = {}
10
11
  commands = ["local_app_setup : Install local requirements for application. (Rails Only Currently)\n",
11
12
  "system_install : Install Homebrew, Ruby, PostgreSQL, and Ruby on Rails\n",
12
- "checkout_repos : Checkout all repositories for StrongMind\n"]
13
+ "checkout_repos : Checkout all repositories for StrongMind\n",
14
+ "console : Open a rails console on ECS\n",
15
+ "ssh : Open a bash shell on ECS\n"
16
+ ]
13
17
 
14
18
  OptionParser.new do |opts|
15
19
  opts.banner = "Usage: smdev.rb [options] <command>"
@@ -22,133 +26,26 @@ module Smdev
22
26
  options[:https] = true
23
27
  end
24
28
 
25
- opts.on("-h", "--help", "Prints this help message") do
26
- puts opts
27
- puts "\nCommands:"
28
- commands.each { |cmd| puts " #{cmd}" }
29
- exit
29
+ opts.on("-r", "--cluster CLUSTER", "Lookup this cluster for the ECS execute (defaults to the name of your current folder)") do |cluster|
30
+ options[:cluster] = cluster
30
31
  end
31
32
 
32
- end.parse!
33
-
34
- def system_install
35
- puts "Installing Homebrew..."
36
- system({ 'SHELL' => '/bin/bash' }, '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"')
37
- # system('/bin/bash', '-c', "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")
38
-
39
- # Add Homebrew to PATH and run initialization script
40
- puts "adding homebrew to .zshrc"
41
- File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
42
- file.write("\n")
43
- file.write('eval "$(/opt/homebrew/bin/brew shellenv)"')
44
- end
45
-
46
- # Update PATH to include Homebrew
47
- ENV['PATH'] = "#{ENV['HOME']}/.homebrew/bin:#{ENV['HOME']}/.homebrew/sbin:#{ENV['PATH']}"
48
-
49
- # Install PostgreSQL
50
- puts "Installing PostgreSQL..."
51
- system('brew', 'install', 'libpq')
52
-
53
- puts "Installing lib-pq..."
54
- system('brew', 'install', 'postgresql@15')
55
-
56
- # Install Code Climate
57
- puts "Preparing Code Climate Formulae..."
58
- system('brew', 'tap', 'codeclimate/formulae')
59
-
60
- puts "Installing Code Climate..."
61
- system('brew', 'install', 'codeclimate')
62
-
63
- # TODO: need to add the path & compiler flags
64
- # echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
65
- # export LDFLAGS="-L/opt/homebrew/opt/libpq/lib"
66
- # export CPPFLAGS="-I/opt/homebrew/opt/libpq/include"
67
-
68
- # Install RBenv
69
- puts "Installing RBenv..."
70
- system('brew', 'install', 'rbenv')
71
- puts "Initialize RBenv..."
72
- File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
73
- file.write("\n")
74
- file.write('eval "$(rbenv init - zsh)"')
33
+ opts.on("-v", "--service SERVICE", "Lookup this service for the ECS execute (defaults to \"prod-worker\")") do |svc|
34
+ options[:service] = svc
75
35
  end
76
- # Load the contents of .zshrc into a string
77
- zshrc_contents = File.read(File.expand_path('~/.zshrc'))
78
-
79
- # Execute a new shell session with the .zshrc contents
80
- exec('zsh', '-c', zshrc_contents)
81
36
 
82
- # Install Ruby
83
- puts "Installing Ruby via RBenv..."
84
- system('rbenv', 'install', '3.2.2')
85
- puts "Making ruby 3.2.2 global ..."
86
- system('rbenv', 'global', '3.2.2')
87
-
88
- # Install Ruby on Rails
89
- puts "Installing Ruby on Rails..."
90
- system('sudo', 'gem', 'install', 'rails')
91
- end
92
- def checkout_repos(options)
93
- token = ENV['GITHUB_TOKEN']
94
- if token.nil?
95
- # Prompt the user for their GitHub personal access token
96
- print "GitHub personal access token: "
97
- token = STDIN.noecho(&:gets).chomp
98
- puts ""
99
- end
100
- # Authenticate with the GitHub API using the user's credentials
101
- client = Octokit::Client.new(access_token: token)
102
-
103
- # Specify the organization name
104
- org_name = "StrongMind"
105
-
106
- if options[:team]
107
- # A team name was provided as a command-line argument
108
- team_name = options[:team]
109
- # Get a list of all teams in the organization
110
- teams = client.organization_teams(org_name)
111
- # Find the team with the specified name
112
- team = teams.find { |t| t.name == team_name }
113
- if team.nil?
114
- puts "Error: Could not find team with name '#{team_name}' in organization '#{org_name}'"
115
- exit
116
- end
117
- # Get a list of all repositories in the organization that are assigned to the specified team
118
- #
119
- repos = client.org_repos(org_name, { :affiliation => 'organization_member', :team_id => team.id })
120
- puts "Team Name #{team_name} - Team ID: #{team.id}"
121
- else
122
- repos = []
123
- page_number = 1
124
- per_page = 100
125
- loop do
126
- repos_page = client.organization_repositories(org_name, { :affiliation => 'owner,organization_member', :per_page => per_page, :page => page_number })
127
- repos.concat(repos_page)
128
- break if repos_page.length < per_page
129
- page_number += 1
130
- end
131
-
132
- # # No team name was provided, so get a list of all teams in the organization
133
- # teams = client.organization_teams(org_name)
134
- # # Get a list of all repositories in the organization that are assigned to each team
135
- # repos = []
136
- # teams.each do |team|
137
- # team_repos = client.team_repos(team.id)
138
- # repos.concat(team_repos)
139
- # end
37
+ opts.on("-c", "--command COMMAND", "Set the command for the ECS execute (defaults to a bash shell when you use 'ssh' and rails console when you use 'console')") do |ecs_command|
38
+ options[:command] = ecs_command
140
39
  end
141
40
 
142
- # Clone each repository to a local directory
143
- repos.each do |repo|
144
- clone_url = repo.clone_url
145
- ssh_url = repo.ssh_url
146
- repo_name = repo.name
147
- url = options[:https] ? clone_url : ssh_url
148
- `git clone #{url} #{repo_name}`
41
+ opts.on("-h", "--help", "Prints this help message") do
42
+ puts opts
43
+ puts "\nCommands:"
44
+ commands.each { |cmd| puts " #{cmd}" }
45
+ exit
149
46
  end
150
47
 
151
- end
48
+ end.parse!
152
49
 
153
50
  command = args.shift
154
51
 
@@ -169,10 +66,150 @@ module Smdev
169
66
  system_install
170
67
  when "checkout_repos"
171
68
  checkout_repos(options)
69
+ when "console"
70
+ options[:command] = "rails c"
71
+ open_ssh(options)
72
+ when "ssh"
73
+ options[:command] ||= "/bin/sh"
74
+ open_ssh(options)
172
75
  else
173
76
  puts "Invalid command: #{command}. Use --help for a list of commands."
174
77
  end
175
78
 
176
79
  end
80
+
81
+ def system_install
82
+ puts "Installing Homebrew..."
83
+ system({ 'SHELL' => '/bin/bash' }, '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"')
84
+ # system('/bin/bash', '-c', "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")
85
+
86
+ # Add Homebrew to PATH and run initialization script
87
+ puts "adding homebrew to .zshrc"
88
+ File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
89
+ file.write("\n")
90
+ file.write('eval "$(/opt/homebrew/bin/brew shellenv)"')
91
+ end
92
+
93
+ # Update PATH to include Homebrew
94
+ ENV['PATH'] = "#{ENV['HOME']}/.homebrew/bin:#{ENV['HOME']}/.homebrew/sbin:#{ENV['PATH']}"
95
+
96
+ # Install PostgreSQL
97
+ puts "Installing PostgreSQL..."
98
+ system('brew', 'install', 'libpq')
99
+
100
+ puts "Installing lib-pq..."
101
+ system('brew', 'install', 'postgresql@15')
102
+
103
+ # Install Code Climate
104
+ puts "Preparing Code Climate Formulae..."
105
+ system('brew', 'tap', 'codeclimate/formulae')
106
+
107
+ puts "Installing Code Climate..."
108
+ system('brew', 'install', 'codeclimate')
109
+
110
+ puts "Installing AWS CLI..."
111
+ system('brew', 'install', 'awscli')
112
+
113
+ puts "Installing AWS Session Manager Plugin..."
114
+ system('brew', 'install', '--cask', 'session-manager-plugin')
115
+
116
+ # TODO: need to add the path & compiler flags
117
+ # echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
118
+ # export LDFLAGS="-L/opt/homebrew/opt/libpq/lib"
119
+ # export CPPFLAGS="-I/opt/homebrew/opt/libpq/include"
120
+
121
+ # Install RBenv
122
+ puts "Installing RBenv..."
123
+ system('brew', 'install', 'rbenv')
124
+ puts "Initialize RBenv..."
125
+ File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
126
+ file.write("\n")
127
+ file.write('eval "$(rbenv init - zsh)"')
128
+ end
129
+ # Load the contents of .zshrc into a string
130
+ zshrc_contents = File.read(File.expand_path('~/.zshrc'))
131
+
132
+ # Execute a new shell session with the .zshrc contents
133
+ exec('zsh', '-c', zshrc_contents)
134
+
135
+ # Install Ruby
136
+ puts "Installing Ruby via RBenv..."
137
+ system('rbenv', 'install', '3.2.2')
138
+ puts "Making ruby 3.2.2 global ..."
139
+ system('rbenv', 'global', '3.2.2')
140
+
141
+ # Install Ruby on Rails
142
+ puts "Installing Ruby on Rails..."
143
+ system('sudo', 'gem', 'install', 'rails')
144
+ end
145
+
146
+ def checkout_repos(options)
147
+ token = ENV['GITHUB_TOKEN']
148
+ if token.nil?
149
+ # Prompt the user for their GitHub personal access token
150
+ print "GitHub personal access token: "
151
+ token = STDIN.noecho(&:gets).chomp
152
+ puts ""
153
+ end
154
+ # Authenticate with the GitHub API using the user's credentials
155
+ client = Octokit::Client.new(access_token: token)
156
+
157
+ # Specify the organization name
158
+ org_name = "StrongMind"
159
+
160
+ if options[:team]
161
+ # A team name was provided as a command-line argument
162
+ team_name = options[:team]
163
+ # Get a list of all teams in the organization
164
+ teams = client.organization_teams(org_name)
165
+ # Find the team with the specified name
166
+ team = teams.find { |t| t.name == team_name }
167
+ if team.nil?
168
+ puts "Error: Could not find team with name '#{team_name}' in organization '#{org_name}'"
169
+ exit
170
+ end
171
+ # Get a list of all repositories in the organization that are assigned to the specified team
172
+ #
173
+ repos = client.org_repos(org_name, { :affiliation => 'organization_member', :team_id => team.id })
174
+ puts "Team Name #{team_name} - Team ID: #{team.id}"
175
+ else
176
+ repos = []
177
+ page_number = 1
178
+ per_page = 100
179
+ loop do
180
+ repos_page = client.organization_repositories(org_name, { :affiliation => 'owner,organization_member', :per_page => per_page, :page => page_number })
181
+ repos.concat(repos_page)
182
+ break if repos_page.length < per_page
183
+ page_number += 1
184
+ end
185
+
186
+ # # No team name was provided, so get a list of all teams in the organization
187
+ # teams = client.organization_teams(org_name)
188
+ # # Get a list of all repositories in the organization that are assigned to each team
189
+ # repos = []
190
+ # teams.each do |team|
191
+ # team_repos = client.team_repos(team.id)
192
+ # repos.concat(team_repos)
193
+ # end
194
+ end
195
+
196
+ # Clone each repository to a local directory
197
+ repos.each do |repo|
198
+ clone_url = repo.clone_url
199
+ ssh_url = repo.ssh_url
200
+ repo_name = repo.name
201
+ url = options[:https] ? clone_url : ssh_url
202
+ `git clone #{url} #{repo_name}`
203
+ end
204
+
205
+ end
206
+
207
+ private
208
+
209
+ def open_ssh(options)
210
+ options[:service] ||= "prod-worker"
211
+ options[:cluster] ||= Dir.pwd.split('/').last
212
+ Smdev::EcsExec.ssh(options)
213
+ end
177
214
  end
178
- end
215
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smdev
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Neighbors
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-11 00:00:00.000000000 Z
11
+ date: 2023-10-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: StrongMind Development Tool
14
14
  email: derek.neighbors@strongmind.com
@@ -19,11 +19,12 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - bin/smdev
21
21
  - lib/smdev.rb
22
+ - lib/smdev/ecs_exec.rb
22
23
  homepage: https://github.com/StrongMind/Helpers/tree/main/smdev
23
24
  licenses:
24
25
  - MIT
25
26
  metadata: {}
26
- post_install_message:
27
+ post_install_message:
27
28
  rdoc_options: []
28
29
  require_paths:
29
30
  - lib
@@ -38,8 +39,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
39
  - !ruby/object:Gem::Version
39
40
  version: '0'
40
41
  requirements: []
41
- rubygems_version: 3.4.13
42
- signing_key:
42
+ rubygems_version: 3.3.5
43
+ signing_key:
43
44
  specification_version: 4
44
45
  summary: StrongMind Development Tool
45
46
  test_files: []