-
-
Save AntoineAugusti/a379d4060da40e1ec4218a4e6e3974dc to your computer and use it in GitHub Desktop.
is_staging_or_prod = Rails.env.production? || Rails.env.staging? | |
dyno_in_run_mode = ENV.fetch('DYNO', 'nope').starts_with?('run') | |
dev_name = ENV.fetch('DEV_NAME', '') | |
if is_staging_or_prod && dyno_in_run_mode | |
raise Drivy::Errors::DevNameNotSetError if dev_name.blank? | |
# Override how printing to sdtout works by sending | |
# the output of stdout to a Slack webhook also. | |
# When writing commands in irb, irb prints to stdout | |
class << STDOUT | |
include Drivy::Console::ReportCommand | |
alias :usual_write :write | |
def write(string) | |
usual_write(string) | |
send_command_to_slack(dev_name, string) | |
end | |
end | |
end |
module Drivy::Console::ReportCommand | |
def send_command_to_slack(developer_name, command_output) | |
return unless has_command? && has_output?(command_output) | |
# Documentation is at https://api.slack.com/docs/message-attachments | |
fields = [ | |
{ | |
title: "Command", | |
value: wrap_command(read_command), | |
short: true, | |
}, | |
{ | |
title: "Output", | |
value: wrap_command(parse_output(command_output)), | |
short: false, | |
}, | |
{ | |
title: "Developer", | |
value: developer_name, | |
short: true, | |
} | |
] | |
env_color, env_title = env_params | |
params = { | |
attachments: [ | |
{ | |
fields: fields, | |
color: env_color, | |
footer: "Console #{env_title} spy", | |
footer_icon: "https://drivy-prod-static.s3.amazonaws.com/slack/spy-small.png", | |
ts: Time.zone.now.to_i, | |
mrkdwn_in: ["fields"], | |
} | |
] | |
} | |
response = slack_client.post('', params) | |
raise "Failed to notify Slack of console command, status: #{response.status}" unless response.success? | |
end | |
private | |
def env_params | |
if Rails.env.production? | |
return ["#e74c3c", "production"] # red | |
elsif Rails.env.staging? | |
return ["#f1c40f", "staging"] # orange | |
else | |
return ["#2ecc71", "development"] # yellow | |
end | |
end | |
def wrap_command(value) | |
"```#{value}```" | |
end | |
def parse_output(command_output) | |
command_output.gsub('=>', '').strip | |
end | |
def has_command? | |
Readline::HISTORY.length >= 1 | |
end | |
def has_output?(command_output) | |
return false unless command_output.instance_of? String | |
command_output.strip.start_with? "=>" | |
end | |
def read_command | |
Readline::HISTORY[Readline::HISTORY.length-1] | |
end | |
def slack_client | |
endpoint = ENV.fetch('SLACK_WEBHOOK_CONSOLE', '') | |
raise "SLACK_WEBHOOK_CONSOLE is not defined" if endpoint.blank? | |
Faraday.new(url: endpoint) do |c| | |
c.request :json | |
c.adapter Faraday.default_adapter | |
end | |
end | |
end |
Hi, Thanks for building this. I was just wondering how to get it to fire on the console load for the first time.
@rahul You're supposed to pass the env variable to the one-off dyno on Heroku. This means, as you found out, passing an env variable to the Heroku CLI.
@mzaragoza You can put it in the initializer. This code is executed at console boot if I remember well. Just after this line https://gist.github.com/AntoineAugusti/a379d4060da40e1ec4218a4e6e3974dc#file-console_spy_initializer-rb-L6 should do the trick.
@AntoineAugusti Thanks for your help.
I was wondering if there is a way to back multiple lines?
An example I type this into the console
def test
puts 'test'
end
then console_spy returns with:
Command: end
Output: : test
I would like that the command would say that the Command would be something like
def test
puts 'test'
end
Thanks
Hey, thank you for this creative way of reporting commands in Rails to slack.
I'm facing an issue that's preventing me from deploying this.
Heroku's build process seems to kick off a
one-off dyno' in order to deploy the application, which satisfies the
dyno_in_run_mode` check in the code.But at the time of deployment,
ENV['DEV_NAME']
isn't expected to be set. We're expecting the dev pass along a temporary environment variable whenever they start the rails console (eg:heroku run EXEC_USER_NAME=rahul rails console
).So, due to the missing DEV_NAME, the deployment fails because
dyno_in_run_mode
is true during deployment.Is this an issue that you've come across?