Skip to content

Instantly share code, notes, and snippets.

@vargonaut
Last active August 24, 2016 15:23
Show Gist options
  • Select an option

  • Save vargonaut/d34b7cced221c7ebee0a25ce4ab4a2ed to your computer and use it in GitHub Desktop.

Select an option

Save vargonaut/d34b7cced221c7ebee0a25ce4ab4a2ed to your computer and use it in GitHub Desktop.
elisp for sending commands to a vagrant instance
;; This send a given command to a vagrant machine
;; The project is an important convention. Its used to:
;; - temporarily cd into the directory for sending the command
;; In my case, my work is in ~/dev/, so it'd be ~/dev/project-name/
;; - its used in the name of the output buffer
;; - its used in the ssh command
;; You'll need an alias to the VM in your ~/.ssh/
;; You can get it with `vagrant ssh-config'.
;; I'd not use 'default', if you've got more than 1.
;;
;; When called:
;; - switch to the project directory (for the command)
;; - pop-to the output buffer (create if it doesn't exist)
;; - turn off read-only
;; - jump to the end of the buffer
;; - insert a divider line
;; - insert a "command prompt" [<date>] <command>
;; - execute the command passing the process to the sentinel to handle output
(defun bb/execute(project command)
(let ((default-directory (format "~/dev/%s/" project)))
(save-window-excursion
(pop-to-buffer (format "*%s-vagrant-command*" project))
(setq inhibit-read-only t)
(goto-char (point-max))
(insert "================================================================================\n")
(insert "[" (format-time-string "%a %b %-e %-I:%M") "] "command "\n\n")
(set-process-sentinel (start-process-shell-command
(format "*%s-vagrant-command*" project)
(format "*%s-vagrant-command*" project)
(concat "ssh -t " project " \"/bin/bash -l -c '" command "'\""))
'bb/post-command-sentinel))))
;; This controls what happens when the process has finished
;; Or, that first conditional makes it so.
;; In this case, it:
;; jumps focus to the output buffer
;; deletes last line in buffer (this was just the new prompt for me)
;; inserts a newline
;; interprets any ansi colors returned so you get 'real' colors
;; turns back on read only
;; sets special mode so you can do like 'q' to bury the buffer
(defun bb/post-command-sentinel(process event)
(if (string-equal event "finished\n")
(progn
(pop-to-buffer (process-buffer process))
(goto-char (point-max))
(forward-line -1)
(delete-region (line-beginning-position)
(line-end-position))
(insert "\n")
(ansi-color-apply-on-region (point-min) (point-max))
(setq inhibit-read-only nil)
(special-mode))))
;;; From here on out, its pretty samey. It should really be macro'd or something.
;;; There are 3 bits to every environment.
;; Make an execute command for the project
(defun bb/pulp-execute(command)
(bb/execute "pulp" command))
;; Initialize the command history list
(setq bb/pulp-command-history '())
;; Our interactive command to the project
;; Its goofy b/c of the autocompletion
(defun bb/pulp-send-command (command)
"Send COMMAND to pulp VM."
(interactive (list (read-from-minibuffer
"Command: "
nil
minibuffer-local-map ; KEYMAP is a keymap to use whilst reading;
nil
'bb/pulp-command-history
'("bundle install" "rake db:migrate") ; defaults
)))
(bb/pulp-execute command))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment