1
;;; rails-ws.el --- functions for manadge application server
2
3
;; Copyright (C) 2006 Dmitry Galinsky <dima dot exe at gmail dot com>
4
5
;; Authors: Dmitry Galinsky <dima dot exe at gmail dot com>,
6
;;          Rezikov Peter <crazypit13 (at) gmail.com>
7
8
;; Keywords: ruby rails languages oop
9
;; $URL$
10
;; $Id$
11
12
;;; License
13
14
;; This program is free software; you can redistribute it and/or
15
;; modify it under the terms of the GNU General Public License
16
;; as published by the Free Software Foundation; either version 2
17
;; of the License, or (at your option) any later version.
18
19
;; This program is distributed in the hope that it will be useful,
20
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
;; GNU General Public License for more details.
23
24
;; You should have received a copy of the GNU General Public License
25
;; along with this program; if not, write to the Free Software
26
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27
28
;;; Code:
29
30
(defcustom rails-ws:port "3000"
31
  "Default web server port"
32
  :group 'rails
33
  :type 'string
34
  :tag "Rails Server Port")
35
36
(defcustom rails-ws:server-name "http://localhost"
37
  "Protocol and the hostname for web server or other rails server"
38
  :group 'rails
39
  :type 'string
40
  :tag "Rails Server Default")
41
42
(defcustom rails-ws:default-server-type "mongrel"
43
  "Web server to run Rails application (Rails version 1 and 2 only)."
44
  :group 'rails
45
  :type 'string
46
  :tag "Rails Server Type")
47
48
(defvar rails-ws:available-servers-list (list "mongrel" "lighttpd" "webrick" "thin"))
49
(defvar rails-ws:buffer-name "*RWebServer*")
50
(defvar rails-ws:process-environment nil)
51
52
(defun rails-ws:default-server-type-p (type)
53
  (string= type rails-ws:default-server-type))
54
55
(defun rails-ws:switch-default-server-type (type)
56
  "Switch default server type to run."
57
  (interactive (list (completing-read "Server type (use autocomplete): "
58
                                      rails-ws:available-servers-list
59
                                      nil t
60
                                      rails-ws:default-server-type)))
61
  (setq rails-ws:default-server-type type)
62
  (customize-save-variable 'rails-ws:default-server-type rails-ws:default-server-type)
63
  (message (concat "Switching to " (upcase type) " as default server type")))
64
65
(defun rails-ws:running-p ()
66
  "Return t if a WebServer process is running."
67
  (if (get-buffer-process rails-ws:buffer-name) t nil))
68
69
(defun rails-ws:sentinel-proc (proc msg)
70
  (let ((env rails-ws:process-environment))
71
    (when (memq (process-status proc) '(exit signal))
72
      (setq rails-ws:process-environment nil)
73
      (setq msg (format "stopped (%s)" msg)))
74
  (message
75
   (replace-regexp-in-string "\n" ""
76
                             (format "%s - %s"
77
                                     (capitalize rails-ws:default-server-type)
78
                                     msg)))))
79
80
(defun rails-ws:start(&optional env)
81
  "Start a server process with ENV environment if ENV is not set
82
using `rails-default-environment'."
83
  (interactive (list (rails-read-enviroment-name)))
84
  (rails-project:with-root
85
   (root)
86
   (let ((proc (get-buffer-process rails-ws:buffer-name)))
87
     (if proc
88
         (message "Only one instance rails-ws allowed")
89
       (progn
90
         (save-excursion
91
           (set-buffer (get-buffer-create rails-ws:buffer-name))
92
           (delete-region (point-min) (point-max))
93
           (rails-minor-mode t))
94
	 (run-hooks 'rails-ws:before-start-hook)
95
	 (let* ((default-directory root)
96
		(env (if env env rails-default-environment))
97
		(command (rails-ws:compute-server-conmmand rails-ws:default-server-type rails-ws:port env))
98
		(proc
99
		 (rails-cmd-proxy:start-process-color rails-ruby-command
100
						rails-ws:buffer-name
101
						(car command)
102
						(cadr command))))
103
           (set-process-sentinel proc 'rails-ws:sentinel-proc)
104
           (setq rails-ws:process-environment env)
105
           (message (format "%s (%s) starting with port %s"
106
                            (capitalize rails-ws:default-server-type)
107
                            env
108
                            rails-ws:port)))
109
	 (run-hooks 'rails-ws:after-start-hook))))))
110
111
(defun rails-ws:compute-server-conmmand (server-type port env)
112
  (cond
113
   ((string= "thin" server-type)
114
    (list server-type
115
           (format "-p %s -e %s start"
116
                   port
117
                   env)))
118
   ((file-exists-p (rails-core:file "script/rails"))
119
    (list rails-ruby-command
120
          (format "script/rails server -p %s -e %s"
121
                  port
122
                  env)))
123
   (t
124
    (list rails-ruby-command
125
          (format "script/server %s -p %s -e %s"
126
                  server-type
127
                  port
128
                  env)))))
129
130
(defun rails-ws:stop ()
131
  "Stop the WebServer process."
132
  (interactive)
133
  (let ((proc (get-buffer-process rails-ws:buffer-name)))
134
    (when proc (kill-process proc t))))
135
136
137
(defun rails-ws:start-default ()
138
  "Start WebServer using the default environment defined in
139
`rails-default-environment'."
140
  (interactive)
141
  (rails-ws:start rails-default-environment))
142
143
(defun rails-ws:start-development ()
144
  (interactive)
145
  (rails-ws:start "development"))
146
147
(defun rails-ws:start-production ()
148
  (interactive)
149
  (rails-ws:start "production"))
150
151
(defun rails-ws:start-test ()
152
  (interactive)
153
  (rails-ws:start "test"))
154
155
(defun rails-ws:toggle-start-stop ()
156
  "Toggle Rails WebServer start/stop with default environment."
157
  (interactive)
158
  (if (rails-ws:running-p)
159
      (rails-ws:stop)
160
    (rails-ws:start-default)))
161
162
(defun rails-ws:print-status ()
163
  (interactive)
164
  (message
165
   (concat rails-ws:default-server-type
166
           " (" (if rails-ws:process-environment
167
                    rails-ws:process-environment
168
                  rails-default-environment) ")"
169
           " is "
170
           (if (rails-ws:running-p)
171
               (concat "running on port " rails-ws:port)
172
             "stopped"))))
173
174
;;;;;;;;;; Open browser ;;;;;;;;;;
175
176
(defun rails-ws:open-browser (&optional address)
177
  "Open a browser on the main page of the current Rails project
178
server."
179
  (interactive)
180
  (let ((url (concat (concat rails-ws:server-name
181
                             ":"
182
                             rails-ws:port
183
                             "/"
184
                             address ))))
185
    (message "Opening browser: %s" url)
186
    (browse-url url)))
187
188
(defun rails-ws:open-browser-on-controller (&optional controller action params)
189
  "Open browser on the controller/action/id for the current
190
file."
191
  (interactive
192
   (list
193
    (completing-read "Controller name: "
194
                     (list->alist (rails-core:controllers t)))
195
    (read-from-minibuffer "Action name: ")
196
    (read-from-minibuffer "Params: ")))
197
  (when (string-not-empty controller)
198
    (rails-ws:open-browser
199
     (concat (rails-core:file-by-class controller t) "/"
200
             (if (string-not-empty action) (concat action "/")) params))))
201
202
(defun rails-ws:auto-open-browser (ask-parameters?)
203
  "Autodetect the current action and open browser on it with.
204
Prefix the command to ask parameters for action."
205
  (interactive "P")
206
  (rails-project:with-root
207
   (root)
208
   (if (find (rails-core:buffer-type) '(:view :controller))
209
       (when-bind (controller (rails-core:current-controller))
210
                  (rails-ws:open-browser-on-controller
211
                   controller (rails-core:current-action)
212
                   (when ask-parameters?
213
                     (read-from-minibuffer "Parameters: "))))
214
     (message "You can auto-open browser only in view or controller"))))
215
216
(provide 'rails-ws)