[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 1 | ; To use this, |
2 | ; 1) Add to init.el: | ||||
3 | ; (setq-default chrome-root "/path/to/chrome/src/") | ||||
4 | ; (add-to-list 'load-path (concat chrome-root "tools/emacs")) | ||||
5 | ; (require 'trybot) | ||||
6 | ; 2) Run on trybot output: | ||||
7 | ; M-x trybot | ||||
8 | ; | ||||
9 | ; To hack on this, | ||||
10 | ; M-x eval-buffer | ||||
[email protected] | e659e96 | 2010-12-03 19:55:35 | [diff] [blame] | 11 | ; M-x trybot-test-win or M-x trybot-test-mac |
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 12 | |
13 | (defvar chrome-root nil | ||||
14 | "Path to the src/ directory of your Chrome checkout.") | ||||
15 | |||||
16 | (defun get-chrome-root () | ||||
17 | (or chrome-root default-directory)) | ||||
18 | |||||
[email protected] | 08062ac | 2010-12-02 00:11:11 | [diff] [blame] | 19 | ; Hunt down from the top, case correcting each path component as needed. |
20 | ; Currently does not keep a cache. Returns nil if no matching file can be | ||||
21 | ; figured out. | ||||
22 | (defun case-corrected-filename (filename) | ||||
23 | (save-match-data | ||||
24 | (let ((path-components (split-string filename "/")) | ||||
25 | (corrected-path (file-name-as-directory (get-chrome-root)))) | ||||
26 | (mapc | ||||
27 | (function | ||||
28 | (lambda (elt) | ||||
29 | (if corrected-path | ||||
30 | (let ((next-component | ||||
31 | (car (member-ignore-case | ||||
32 | elt (directory-files corrected-path))))) | ||||
33 | (setq corrected-path | ||||
34 | (and next-component | ||||
35 | (file-name-as-directory | ||||
36 | (concat corrected-path next-component)))))))) | ||||
37 | path-components) | ||||
38 | (if corrected-path | ||||
39 | (file-relative-name (directory-file-name corrected-path) | ||||
40 | (get-chrome-root)) | ||||
41 | nil)))) | ||||
42 | |||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 43 | (defun trybot-fixup-win () |
44 | "Fix up Windows-specific output." | ||||
45 | |||||
46 | ; Fix Windows paths ("d:\...\src\"). | ||||
47 | (save-excursion | ||||
[email protected] | ba18686 | 2011-01-26 20:52:56 | [diff] [blame] | 48 | ; This regexp is subtle and rather hard to read. :~( |
49 | ; Use regexp-builder when making changes to it. | ||||
50 | (while (re-search-forward | ||||
51 | (concat | ||||
52 | ; First part: path leader, either of the form | ||||
53 | ; e:\...src\ or ..\ | ||||
54 | "\\(^.:\\\\.*\\\\src\\\\\\|\\.\\.\\\\\\)" | ||||
55 | ; Second part: path, followed by error message marker. | ||||
56 | "\\(.*?\\)[(:]") nil t) | ||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 57 | (replace-match "" nil t nil 1) |
58 | ; Line now looks like: | ||||
59 | ; foo\bar\baz.cc error message here | ||||
60 | ; We want to fixup backslashes in path into forward slashes, | ||||
61 | ; without modifying the error message - by matching up to the | ||||
62 | ; first colon above (which will be just beyond the end of the | ||||
63 | ; filename) we can use the end of the match as a limit. | ||||
64 | (subst-char-in-region (point) (match-end 0) ?\\ ?/) | ||||
65 | ; See if we can correct the file name casing. | ||||
66 | (let ((filename (buffer-substring (match-beginning 2) (match-end 2)))) | ||||
67 | (if (and (not (file-exists-p filename)) | ||||
68 | (setq filename (case-corrected-filename filename))) | ||||
69 | (replace-match filename t t nil 2)))))) | ||||
70 | |||||
71 | (defun trybot-fixup-maclin () | ||||
72 | "Fix up Mac/Linux output." | ||||
73 | (save-excursion | ||||
74 | (while (re-search-forward "^/b/build/[^ ]*/src/" nil t) | ||||
75 | (replace-match "")))) | ||||
76 | |||||
77 | (defun trybot-fixup (type-hint) | ||||
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 78 | "Parse and fixup the contents of the current buffer as trybot output." |
79 | |||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 80 | ; XXX is there something I should so so this stuff doesn't end up on the |
81 | ; undo stack? | ||||
82 | |||||
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 83 | ;; Fixup paths. |
84 | (cd (get-chrome-root)) | ||||
85 | |||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 86 | (goto-char (point-min)) |
87 | |||||
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 88 | ;; Fix up path references. |
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 89 | (cond ((eq type-hint 'win) (trybot-fixup-win)) |
90 | ((eq type-hint 'mac) (trybot-fixup-maclin)) | ||||
91 | ((eq type-hint 'linux) (trybot-fixup-maclin)) | ||||
92 | (t (trybot-fixup-win) (trybot-fixup-maclin))) | ||||
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 93 | |
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 94 | (compilation-mode)) |
95 | |||||
[email protected] | 15e4d5b0 | 2010-12-13 23:34:46 | [diff] [blame] | 96 | (defun trybot-get-new-buffer () |
97 | "Get a new clean buffer for trybot output." | ||||
98 | ; Use trybot-buffer-name if available; otherwise, "*trybot*". | ||||
99 | (let ((buffer-name (if (boundp 'trybot-buffer-name) | ||||
100 | trybot-buffer-name | ||||
101 | "*trybot*"))) | ||||
102 | (let ((old (get-buffer buffer-name))) | ||||
103 | (when old (kill-buffer old))) | ||||
104 | (get-buffer-create buffer-name))) | ||||
105 | |||||
106 | (defun trybot-fetch (type-hint url) | ||||
107 | "Fetch a URL and postprocess it as trybot output." | ||||
108 | |||||
109 | (let ((on-fetch-completion | ||||
110 | (lambda (process state) | ||||
111 | (switch-to-buffer (process-buffer process)) | ||||
112 | (when (equal state "finished\n") | ||||
113 | (trybot-fixup (process-get process 'type-hint))))) | ||||
[email protected] | 094b70569 | 2010-12-17 03:46:15 | [diff] [blame] | 114 | (command (concat "curl -s " (shell-quote-argument url) |
115 | ; Pipe it through the output shortener. | ||||
116 | (cond | ||||
117 | ((eq type-hint 'win) | ||||
[email protected] | 15e4d5b0 | 2010-12-13 23:34:46 | [diff] [blame] | 118 | (concat " | " (get-chrome-root) |
[email protected] | 094b70569 | 2010-12-17 03:46:15 | [diff] [blame] | 119 | "build/sanitize-win-build-log.sh")) |
120 | ((eq type-hint 'mac) | ||||
121 | (concat " | " (get-chrome-root) | ||||
122 | "build/sanitize-mac-build-log.sh")))))) | ||||
[email protected] | 15e4d5b0 | 2010-12-13 23:34:46 | [diff] [blame] | 123 | |
124 | ; Start up the subprocess. | ||||
125 | (let* ((coding-system-for-read 'utf-8-dos) | ||||
126 | (buffer (trybot-get-new-buffer)) | ||||
127 | (process (start-process-shell-command "curl" buffer command))) | ||||
128 | ; Attach the type hint to the process so we can get it back when | ||||
129 | ; the process completes. | ||||
130 | (process-put process 'type-hint type-hint) | ||||
131 | (set-process-query-on-exit-flag process nil) | ||||
132 | (set-process-sentinel process on-fetch-completion)))) | ||||
133 | |||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 134 | (defun trybot-test (type-hint filename) |
[email protected] | e659e96 | 2010-12-03 19:55:35 | [diff] [blame] | 135 | "Load the given test data filename and do the trybot parse on it." |
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 136 | |
[email protected] | 15e4d5b0 | 2010-12-13 23:34:46 | [diff] [blame] | 137 | (let ((trybot-buffer-name "*trybot-test*") |
138 | (url (concat "file://" (get-chrome-root) "tools/emacs/" filename))) | ||||
139 | (trybot-fetch type-hint url))) | ||||
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 140 | |
[email protected] | e659e96 | 2010-12-03 19:55:35 | [diff] [blame] | 141 | (defun trybot-test-win () |
142 | "Load the Windows test data and do the trybot parse on it." | ||||
143 | (interactive) | ||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 144 | (trybot-test 'win "trybot-windows.txt")) |
[email protected] | e659e96 | 2010-12-03 19:55:35 | [diff] [blame] | 145 | (defun trybot-test-mac () |
146 | "Load the Mac test data and do the trybot parse on it." | ||||
147 | (interactive) | ||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 148 | (trybot-test 'mac "trybot-mac.txt")) |
[email protected] | 5dd3199 | 2010-12-10 21:27:00 | [diff] [blame] | 149 | (defun trybot-test-linux () |
150 | "Load the Linux test data and do the trybot parse on it." | ||||
151 | (interactive) | ||||
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 152 | (trybot-test 'linux "trybot-linux.txt")) |
[email protected] | e659e96 | 2010-12-03 19:55:35 | [diff] [blame] | 153 | |
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 154 | (defun trybot (url) |
155 | "Fetch a trybot URL and fix up the output into a compilation-mode buffer." | ||||
156 | (interactive "sURL to trybot stdout (leave empty to use clipboard): ") | ||||
157 | |||||
158 | ;; Yank URL from clipboard if necessary. | ||||
159 | (when (= (length url) 0) | ||||
160 | (with-temp-buffer | ||||
161 | (clipboard-yank) | ||||
162 | (setq url (buffer-string)))) | ||||
163 | |||||
[email protected] | 0917cf3 | 2010-12-14 20:43:02 | [diff] [blame] | 164 | ;; Append /text to the URL to get plain text output in the common |
165 | ;; case of getting a URL to the HTML build log. | ||||
166 | (when (equal "stdio" (car (last (split-string url "/")))) | ||||
167 | (setq url (concat url "/text"))) | ||||
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 168 | |
[email protected] | 094b70569 | 2010-12-17 03:46:15 | [diff] [blame] | 169 | (let ((type-hint (cond ((string-match "/[Ww]in" url) 'win) |
[email protected] | f02c804 | 2010-12-13 21:48:15 | [diff] [blame] | 170 | ((string-match "/mac/" url) 'mac) |
171 | ; Match /linux, /linux_view, etc. | ||||
172 | ((string-match "/linux" url) 'linux) | ||||
173 | (t 'unknown)))) | ||||
[email protected] | 15e4d5b0 | 2010-12-13 23:34:46 | [diff] [blame] | 174 | (trybot-fetch type-hint url))) |
[email protected] | 1b38cfbe | 2010-12-01 00:38:50 | [diff] [blame] | 175 | |
176 | (provide 'trybot) |