1
;;; rails-rake.el --- emacs-rails integraions with rake tasks.
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
7
;; Keywords: ruby rails languages oop
8
;; $URL: svn+ssh://rubyforge/var/svn/emacs-rails/trunk/rails-scripts.el $
9
;; $Id: rails-scripts.el 117 2007-03-25 23:37:37Z dimaexe $
10
11
;;; License
12
13
;; This program is free software; you can redistribute it and/or
14
;; modify it under the terms of the GNU General Public License
15
;; as published by the Free Software Foundation; either version 2
16
;; of the License, or (at your option) any later version.
17
18
;; This program is distributed in the hope that it will be useful,
19
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
;; GNU General Public License for more details.
22
23
;; You should have received a copy of the GNU General Public License
24
;; along with this program; if not, write to the Free Software
25
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26
27
(eval-when-compile
28
  (require 'rails-scripts))
29
30
(defcustom rails-rake-use-bundler-when-possible t
31
  "t when rake should be run with 'bundle exec' whenever possible. (Gemfile present)"
32
  :group 'rails
33
  :type 'boolean)
34
35
(defvar rails-rake:history (list))
36
37
(defvar rails-rake:tasks-regexp "^rake \\([^ ]*\\).*# \\(.*\\)"
38
  "Regexp to match tasks list in `rake --tasks` output.")
39
40
(defun rails-rake:create-tasks-cache (file-name)
41
  "Create a cache file from rake --tasks output."
42
  (let ((tasks (loop for str in (split-string (rails-cmd-proxy:shell-command-to-string (rails-rake:rake-command "--task")) "\n")
43
                     for task = (when (string-not-empty str)
44
                                  (string=~ rails-rake:tasks-regexp str $1))
45
                     when task collect task)))
46
    (write-string-to-file file-name (prin1-to-string tasks))
47
    tasks))
48
49
(defun rails-rake:list-of-tasks ()
50
  "Return all available tasks and create tasks cache file."
51
  (rails-project:in-root
52
   (let* ((cache-file (rails-core:file "tmp/.tasks-cache")))
53
     (if (file-exists-p cache-file)
54
         (read-from-file cache-file)
55
       (rails-rake:create-tasks-cache cache-file)))))
56
57
(defun rails-rake:list-of-tasks-without-tests ()
58
  "Return available tasks without test actions."
59
  (when-bind
60
   (tasks (rails-rake:list-of-tasks))
61
   (sort (delete* nil
62
                  (mapcar
63
                   #'(lambda (it) (if (string=~ "^test\\($\\|:\\)" it t) nil it))
64
                   (rails-rake:list-of-tasks))
65
                  :if 'null)
66
         'string<)))
67
68
(defun rails-rake:task (task &optional major-mode mode-line-string)
69
  "Run a Rake task in RAILS_ROOT with MAJOR-MODE, using mode-line-string as the script name."
70
  (interactive (rails-completing-read "What task run" (rails-rake:list-of-tasks-without-tests)
71
                                      'rails-rake:history nil))
72
  (when task
73
    (rails-script:run (rails-rake:rake-command) (list task) major-mode (or mode-line-string (concat (rails-rake:rake-command " ") task)))))
74
75
(defun rails-rake:migrate (&optional version)
76
  "Run the db:migrate task"
77
  (interactive)
78
  (rails-rake:task
79
   (concat
80
    "db:migrate"
81
    (typecase version
82
      (integer (format " VERSION=%.3i" version))
83
      (string (format " VERSION=%s" version))))))
84
85
(defun rails-rake:migrate-to-version (version)
86
  "Run migrate with VERSION."
87
  (interactive (rails-completing-read "Version of migration"
88
                                      (rails-core:migration-versions t)
89
                                      nil
90
                                      t))
91
  (when version
92
    (rails-rake:migrate version)))
93
94
(defun rails-rake:migrate-to-prev-version ()
95
  "Migrate to a previous version."
96
  (interactive)
97
  (let ((versions (rails-core:migration-versions t)))
98
    (rails-rake:migrate
99
     (when (< 2  (length versions))
100
       (nth 1 versions)))))
101
102
(defun rails-rake:migrate-version (&optional version direction)
103
  "Run the db:migration:(up|down) task"
104
  (interactive)
105
  (if (string-equal "" version)
106
      (setq version (rails-core:current-migration-version)))
107
  (rails-rake:task
108
   (concat
109
    "db:migrate"
110
    (cond ((string-equal direction "up") ":up")
111
          ((string-equal direction "down") ":down"))
112
    (typecase version
113
      (integer (format " VERSION=%.3i" version))
114
      (string (format " VERSION=%s" version))))))
115
116
(defun rails-rake:migration-version-up (&optional version)
117
  "Run up migration with VERSION."
118
  (interactive (rails-completing-read "Version of migration"
119
                                      (rails-core:migration-versions t)
120
                                      nil
121
                                      t))
122
  (when version
123
    (rails-rake:migrate-version version "up")))
124
125
(defun rails-rake:migration-version-down (&optional version)
126
  "Run up migration with VERSION."
127
  (interactive (rails-completing-read "Version of migration"
128
                                      (rails-core:migration-versions t)
129
                                      nil
130
                                      t))
131
  (when version
132
    (rails-rake:migrate-version version "down")))
133
134
;; This function was originally defined anonymously in ui. It was defined here so keys
135
;; can be added to it dryly
136
(defun rails-rake:clone-development-db-to-test-db ()
137
  "Clone development DB to test DB."
138
  (interactive) (rails-rake:task "db:test:clone"))
139
140
(defun rails-rake:rake-command (&optional args)
141
  (if (and rails-rake-use-bundler-when-possible (file-exists-p (rails-core:file "Gemfile")))
142
      (concat "bundle exec rake " args) (concat "rake " args)))
143
144
(provide 'rails-rake)