15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); To use this,
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); 1) Add to init.el:
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles);    (setq-default chrome-root "/path/to/chrome/src/")
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles);    (add-to-list 'load-path (concat chrome-root "tools/emacs"))
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles);    (require 'trybot)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); 2) Run on trybot output:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles);    M-x trybot
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles);
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); To hack on this,
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); M-x eval-buffer
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); M-x trybot-test-win  or  M-x trybot-test-mac
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defvar chrome-root nil
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Path to the src/ directory of your Chrome checkout.")
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun get-chrome-root ()
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (or chrome-root default-directory))
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); Hunt down from the top, case correcting each path component as needed.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); Currently does not keep a cache.  Returns nil if no matching file can be
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); figured out.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun case-corrected-filename (filename)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (save-match-data
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (let ((path-components (split-string filename "/"))
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (corrected-path (file-name-as-directory (get-chrome-root))))
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (mapc
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       (function
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (lambda (elt)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (if corrected-path
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              (let ((next-component
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     (car (member-ignore-case
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           elt (directory-files corrected-path)))))
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                (setq corrected-path
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      (and next-component
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           (file-name-as-directory
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            (concat corrected-path next-component))))))))
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       path-components)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (if corrected-path
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (file-relative-name (directory-file-name corrected-path)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              (get-chrome-root))
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nil))))
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-fixup-win ()
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Fix up Windows-specific output."
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ; Fix Windows paths ("d:\...\src\").
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (save-excursion
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ; This regexp is subtle and rather hard to read. :~(
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ; Use regexp-builder when making changes to it.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (while (re-search-forward
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (concat
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             ; First part: path leader, either of the form
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             ;   e:\...src\  or  ..\
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\\(^.:\\\\.*\\\\src\\\\\\|\\.\\.\\\\\\)"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             ; Second part: path, followed by error message marker.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\\(.*?\\)[(:]") nil t)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (replace-match "" nil t nil 1)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; Line now looks like:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;  foo\bar\baz.cc error message here
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; We want to fixup backslashes in path into forward slashes,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; without modifying the error message - by matching up to the
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; first colon above (which will be just beyond the end of the
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; filename) we can use the end of the match as a limit.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (subst-char-in-region (point) (match-end 0) ?\\ ?/)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; See if we can correct the file name casing.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (let ((filename (buffer-substring (match-beginning 2) (match-end 2))))
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (if (and (not (file-exists-p filename))
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 (setq filename (case-corrected-filename filename)))
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (replace-match filename t t nil 2))))))
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-fixup-maclin ()
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Fix up Mac/Linux output."
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (save-excursion
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (while (re-search-forward "^/b/build/[^ ]*/src/" nil t)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (replace-match ""))))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-fixup (type-hint)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Parse and fixup the contents of the current buffer as trybot output."
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ; XXX is there something I should so so this stuff doesn't end up on the
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ; undo stack?
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ;; Fixup paths.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (cd (get-chrome-root))
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (goto-char (point-min))
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ;; Fix up path references.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (cond ((eq type-hint 'win) (trybot-fixup-win))
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ((eq type-hint 'mac) (trybot-fixup-maclin))
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ((eq type-hint 'linux) (trybot-fixup-maclin))
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (t (trybot-fixup-win) (trybot-fixup-maclin)))
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (compilation-mode))
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-get-new-buffer ()
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Get a new clean buffer for trybot output."
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ; Use trybot-buffer-name if available; otherwise, "*trybot*".
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (let ((buffer-name (if (boundp 'trybot-buffer-name)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         trybot-buffer-name
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "*trybot*")))
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (let ((old (get-buffer buffer-name)))
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (when old (kill-buffer old)))
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (get-buffer-create buffer-name)))
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-fetch (type-hint url)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Fetch a URL and postprocess it as trybot output."
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (let ((on-fetch-completion
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (lambda (process state)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (switch-to-buffer (process-buffer process))
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (when (equal state "finished\n")
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             (trybot-fixup (process-get process 'type-hint)))))
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (command (concat "curl -s " (shell-quote-argument url)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ; Pipe it through the output shortener.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         (cond
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ((eq type-hint 'win)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           (concat " | " (get-chrome-root)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "build/sanitize-win-build-log.sh"))
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ((eq type-hint 'mac)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           (concat " | " (get-chrome-root)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "build/sanitize-mac-build-log.sh"))))))
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ; Start up the subprocess.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (let* ((coding-system-for-read 'utf-8-dos)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (buffer (trybot-get-new-buffer))
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (process (start-process-shell-command "curl" buffer command)))
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; Attach the type hint to the process so we can get it back when
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ; the process completes.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (process-put process 'type-hint type-hint)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (set-process-query-on-exit-flag process nil)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (set-process-sentinel process on-fetch-completion))))
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-test (type-hint filename)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Load the given test data filename and do the trybot parse on it."
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (let ((trybot-buffer-name "*trybot-test*")
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (url (concat "file://" (get-chrome-root) "tools/emacs/" filename)))
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (trybot-fetch type-hint url)))
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-test-win ()
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Load the Windows test data and do the trybot parse on it."
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (interactive)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (trybot-test 'win "trybot-windows.txt"))
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-test-mac ()
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Load the Mac test data and do the trybot parse on it."
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (interactive)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (trybot-test 'mac "trybot-mac.txt"))
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot-test-linux ()
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Load the Linux test data and do the trybot parse on it."
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (interactive)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (trybot-test 'linux "trybot-linux.txt"))
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(defun trybot (url)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Fetch a trybot URL and fix up the output into a compilation-mode buffer."
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (interactive "sURL to trybot stdout (leave empty to use clipboard): ")
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ;; Yank URL from clipboard if necessary.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (when (= (length url) 0)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (with-temp-buffer
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (clipboard-yank)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (setq url (buffer-string))))
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ;; Append /text to the URL to get plain text output in the common
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ;; case of getting a URL to the HTML build log.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (when (equal "stdio" (car (last (split-string url "/"))))
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (setq url (concat url "/text")))
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (let ((type-hint (cond ((string-match "/[Ww]in" url) 'win)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ((string-match "/mac/" url) 'mac)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ; Match /linux, /linux_view, etc.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ((string-match "/linux" url) 'linux)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         (t 'unknown))))
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (trybot-fetch type-hint url)))
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(provide 'trybot)
177