| ; To use this, |
| ; 1) Add to init.el: |
| ; (setq-default chrome-root "/path/to/chrome/src/") |
| ; (add-to-list 'load-path (concat chrome-root "tools/emacs")) |
| ; (require 'trybot) |
| ; 2) Run on trybot output: |
| ; M-x trybot |
| ; |
| ; To hack on this, |
| ; M-x eval-buffer |
| ; M-x trybot-test-win or M-x trybot-test-mac |
| |
| (defvar chrome-root nil |
| "Path to the src/ directory of your Chrome checkout.") |
| |
| (defun get-chrome-root () |
| (or chrome-root default-directory)) |
| |
| ; Hunt down from the top, case correcting each path component as needed. |
| ; Currently does not keep a cache. Returns nil if no matching file can be |
| ; figured out. |
| (defun case-corrected-filename (filename) |
| (save-match-data |
| (let ((path-components (split-string filename "/")) |
| (corrected-path (file-name-as-directory (get-chrome-root)))) |
| (mapc |
| (function |
| (lambda (elt) |
| (if corrected-path |
| (let ((next-component |
| (car (member-ignore-case |
| elt (directory-files corrected-path))))) |
| (setq corrected-path |
| (and next-component |
| (file-name-as-directory |
| (concat corrected-path next-component)))))))) |
| path-components) |
| (if corrected-path |
| (file-relative-name (directory-file-name corrected-path) |
| (get-chrome-root)) |
| nil)))) |
| |
| (defun trybot-fixup-win () |
| "Fix up Windows-specific output." |
| |
| ; Fix Windows paths ("d:\...\src\"). |
| (save-excursion |
| ; This regexp is subtle and rather hard to read. :~( |
| ; Use regexp-builder when making changes to it. |
| (while (re-search-forward |
| (concat |
| ; First part: path leader, either of the form |
| ; e:\...src\ or ..\ |
| "\\(^.:\\\\.*\\\\src\\\\\\|\\.\\.\\\\\\)" |
| ; Second part: path, followed by error message marker. |
| "\\(.*?\\)[(:]") nil t) |
| (replace-match "" nil t nil 1) |
| ; Line now looks like: |
| ; foo\bar\baz.cc error message here |
| ; We want to fixup backslashes in path into forward slashes, |
| ; without modifying the error message - by matching up to the |
| ; first colon above (which will be just beyond the end of the |
| ; filename) we can use the end of the match as a limit. |
| (subst-char-in-region (point) (match-end 0) ?\\ ?/) |
| ; See if we can correct the file name casing. |
| (let ((filename (buffer-substring (match-beginning 2) (match-end 2)))) |
| (if (and (not (file-exists-p filename)) |
| (setq filename (case-corrected-filename filename))) |
| (replace-match filename t t nil 2)))))) |
| |
| (defun trybot-fixup-maclin () |
| "Fix up Mac/Linux output." |
| (save-excursion |
| (while (re-search-forward "^/b/build/[^ ]*/src/" nil t) |
| (replace-match "")))) |
| |
| (defun trybot-fixup (type-hint) |
| "Parse and fixup the contents of the current buffer as trybot output." |
| |
| ; XXX is there something I should so so this stuff doesn't end up on the |
| ; undo stack? |
| |
| ;; Fixup paths. |
| (cd (get-chrome-root)) |
| |
| (goto-char (point-min)) |
| |
| ;; Fix up path references. |
| (cond ((eq type-hint 'win) (trybot-fixup-win)) |
| ((eq type-hint 'mac) (trybot-fixup-maclin)) |
| ((eq type-hint 'linux) (trybot-fixup-maclin)) |
| (t (trybot-fixup-win) (trybot-fixup-maclin))) |
| |
| (compilation-mode)) |
| |
| (defun trybot-get-new-buffer () |
| "Get a new clean buffer for trybot output." |
| ; Use trybot-buffer-name if available; otherwise, "*trybot*". |
| (let ((buffer-name (if (boundp 'trybot-buffer-name) |
| trybot-buffer-name |
| "*trybot*"))) |
| (let ((old (get-buffer buffer-name))) |
| (when old (kill-buffer old))) |
| (get-buffer-create buffer-name))) |
| |
| (defun trybot-fetch (type-hint url) |
| "Fetch a URL and postprocess it as trybot output." |
| |
| (let ((on-fetch-completion |
| (lambda (process state) |
| (switch-to-buffer (process-buffer process)) |
| (when (equal state "finished\n") |
| (trybot-fixup (process-get process 'type-hint))))) |
| (command (concat "curl -s " (shell-quote-argument url) |
| ; Pipe it through the output shortener. |
| (cond |
| ((eq type-hint 'win) |
| (concat " | " (get-chrome-root) |
| "build/sanitize-win-build-log.sh")) |
| ((eq type-hint 'mac) |
| (concat " | " (get-chrome-root) |
| "build/sanitize-mac-build-log.sh")))))) |
| |
| ; Start up the subprocess. |
| (let* ((coding-system-for-read 'utf-8-dos) |
| (buffer (trybot-get-new-buffer)) |
| (process (start-process-shell-command "curl" buffer command))) |
| ; Attach the type hint to the process so we can get it back when |
| ; the process completes. |
| (process-put process 'type-hint type-hint) |
| (set-process-query-on-exit-flag process nil) |
| (set-process-sentinel process on-fetch-completion)))) |
| |
| (defun trybot-test (type-hint filename) |
| "Load the given test data filename and do the trybot parse on it." |
| |
| (let ((trybot-buffer-name "*trybot-test*") |
| (url (concat "file://" (get-chrome-root) "tools/emacs/" filename))) |
| (trybot-fetch type-hint url))) |
| |
| (defun trybot-test-win () |
| "Load the Windows test data and do the trybot parse on it." |
| (interactive) |
| (trybot-test 'win "trybot-windows.txt")) |
| (defun trybot-test-mac () |
| "Load the Mac test data and do the trybot parse on it." |
| (interactive) |
| (trybot-test 'mac "trybot-mac.txt")) |
| (defun trybot-test-linux () |
| "Load the Linux test data and do the trybot parse on it." |
| (interactive) |
| (trybot-test 'linux "trybot-linux.txt")) |
| |
| (defun trybot (url) |
| "Fetch a trybot URL and fix up the output into a compilation-mode buffer." |
| (interactive "sURL to trybot stdout (leave empty to use clipboard): ") |
| |
| ;; Yank URL from clipboard if necessary. |
| (when (= (length url) 0) |
| (with-temp-buffer |
| (clipboard-yank) |
| (setq url (buffer-string)))) |
| |
| ;; Append /text to the URL to get plain text output in the common |
| ;; case of getting a URL to the HTML build log. |
| (when (equal "stdio" (car (last (split-string url "/")))) |
| (setq url (concat url "/text"))) |
| |
| (let ((type-hint (cond ((string-match "/[Ww]in" url) 'win) |
| ((string-match "/mac/" url) 'mac) |
| ; Match /linux, /linux_view, etc. |
| ((string-match "/linux" url) 'linux) |
| (t 'unknown)))) |
| (trybot-fetch type-hint url))) |
| |
| (provide 'trybot) |