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.
- checksums.yaml +4 -4
- data/lib/smdev/ecs_exec.rb +92 -0
- data/lib/smdev.rb +158 -121
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 61964b5c32328c5e2265a32622cb85c366a70780eeaab4b95e154577942602b9
|
|
4
|
+
data.tar.gz: 39c56ddd43405021c465494bf439e174681e431146e59a808937f0c6592a2f97
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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("-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
83
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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.
|
|
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-
|
|
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.
|
|
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: []
|