recap 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +2 -1
  2. data/README.md +55 -10
  3. data/Rakefile +19 -5
  4. data/bin/recap +2 -2
  5. data/features/managing-processes.feature +1 -1
  6. data/features/setting-environment-variables.feature +26 -1
  7. data/features/steps/capistrano_steps.rb +10 -6
  8. data/features/support/project.rb +24 -5
  9. data/features/templates/project/Capfile.erb +1 -1
  10. data/lib/recap/recipes/rails.rb +6 -0
  11. data/lib/recap/recipes/ruby.rb +11 -0
  12. data/lib/recap/recipes/static.rb +3 -0
  13. data/lib/recap/recipes.rb +18 -0
  14. data/lib/recap/support/capistrano_extensions.rb +85 -0
  15. data/lib/recap/support/cli.rb +57 -0
  16. data/lib/recap/{compatibility.rb → support/compatibility.rb} +2 -2
  17. data/lib/recap/support/environment.rb +61 -0
  18. data/lib/recap/support/namespace.rb +47 -0
  19. data/lib/recap/support/shell_command.rb +35 -0
  20. data/lib/recap/support/templates/Capfile.erb +6 -0
  21. data/lib/recap/tasks/bootstrap.rb +77 -0
  22. data/lib/recap/{bundler.rb → tasks/bundler.rb} +15 -6
  23. data/lib/recap/{deploy.rb → tasks/deploy.rb} +30 -17
  24. data/lib/recap/tasks/env.rb +111 -0
  25. data/lib/recap/{foreman.rb → tasks/foreman.rb} +20 -12
  26. data/lib/recap/{preflight.rb → tasks/preflight.rb} +13 -11
  27. data/lib/recap/tasks/rails.rb +42 -0
  28. data/lib/recap/tasks.rb +16 -0
  29. data/lib/recap/version.rb +1 -1
  30. data/lib/recap.rb +119 -10
  31. data/recap.gemspec +3 -2
  32. data/spec/models/capistrano_extensions_spec.rb +41 -0
  33. data/spec/models/cli_spec.rb +25 -0
  34. data/spec/models/environment_spec.rb +14 -14
  35. data/spec/models/shell_command_spec.rb +55 -0
  36. data/spec/spec_helper.rb +1 -1
  37. data/spec/tasks/bootstrap_spec.rb +9 -13
  38. data/spec/tasks/bundler_spec.rb +39 -7
  39. data/spec/tasks/deploy_spec.rb +42 -26
  40. data/spec/tasks/env_spec.rb +81 -5
  41. data/spec/tasks/foreman_spec.rb +10 -5
  42. data/spec/tasks/rails_spec.rb +80 -0
  43. metadata +65 -57
  44. data/doc/index.html +0 -235
  45. data/doc/lib/recap/bootstrap.html +0 -42
  46. data/doc/lib/recap/bundler.html +0 -168
  47. data/doc/lib/recap/capistrano_extensions.html +0 -208
  48. data/doc/lib/recap/cli.html +0 -42
  49. data/doc/lib/recap/compatibility.html +0 -73
  50. data/doc/lib/recap/deploy.html +0 -328
  51. data/doc/lib/recap/env.html +0 -108
  52. data/doc/lib/recap/foreman.html +0 -42
  53. data/doc/lib/recap/namespace.html +0 -42
  54. data/doc/lib/recap/preflight.html +0 -163
  55. data/doc/lib/recap/rails.html +0 -42
  56. data/doc/lib/recap/version.html +0 -42
  57. data/doc/lib/recap.html +0 -42
  58. data/index.rb +0 -62
  59. data/lib/recap/bootstrap.rb +0 -47
  60. data/lib/recap/capistrano_extensions.rb +0 -74
  61. data/lib/recap/cli.rb +0 -32
  62. data/lib/recap/deploy/templates/Capfile.erb +0 -6
  63. data/lib/recap/env.rb +0 -58
  64. data/lib/recap/environment.rb +0 -54
  65. data/lib/recap/namespace.rb +0 -37
  66. data/lib/recap/rails.rb +0 -24
  67. data/lib/recap/ruby.rb +0 -3
  68. data/lib/recap/static.rb +0 -1
@@ -1,163 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
- <title>preflight.rb</title>
6
- <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
- </head>
8
- <body>
9
- <div id='container'>
10
- <div id="background"></div>
11
- <div id="jump_to">
12
- Jump To &hellip;
13
- <div id="jump_wrapper">
14
- <div id="jump_page">
15
- <a class="source" href="../../index.html">index.rb</a>
16
- <a class="source" href="../recap.html">recap.rb</a>
17
- <a class="source" href="bootstrap.html">bootstrap.rb</a>
18
- <a class="source" href="bundler.html">bundler.rb</a>
19
- <a class="source" href="capistrano_extensions.html">capistrano_extensions.rb</a>
20
- <a class="source" href="cli.html">cli.rb</a>
21
- <a class="source" href="compatibility.html">compatibility.rb</a>
22
- <a class="source" href="deploy.html">deploy.rb</a>
23
- <a class="source" href="env.html">env.rb</a>
24
- <a class="source" href="foreman.html">foreman.rb</a>
25
- <a class="source" href="namespace.html">namespace.rb</a>
26
- <a class="source" href="preflight.html">preflight.rb</a>
27
- <a class="source" href="rails.html">rails.rb</a>
28
- <a class="source" href="version.html">version.rb</a>
29
- </div>
30
- </div>
31
- </div>
32
- <table cellspacing=0 cellpadding=0>
33
- <thead>
34
- <tr>
35
- <th class=docs><h1>preflight.rb</h1></th>
36
- <th class=code></th>
37
- </tr>
38
- </thead>
39
- <tbody>
40
- <tr id='section-1'>
41
- <td class=docs>
42
- <div class="pilwrap">
43
- <a class="pilcrow" href="#section-1">&#182;</a>
44
- </div>
45
- <p>Before <code>recap</code> will work correctly, a small amount of setup work needs to be performed on
46
- all target servers.</p>
47
-
48
- <p>First, each user who can deploy the app needs to have an account on each server, and must be able
49
- to ssh into the box. They&rsquo;ll also each need to be sudoers.</p>
50
-
51
- <p>Secondly, each deploying user should set their git <code>user.name</code> and <code>user.email</code>. This can easily
52
- be done by running:</p>
53
-
54
- <p><code>git config &mdash;global user.email &ldquo;you@example.com&rdquo;</code>
55
- <code>git config &mdash;global user.name &ldquo;Your Name&rdquo;</code></p>
56
-
57
- <p>Finally, a user and group representing the application (and usually with the same name) should be
58
- created. Where possible, the application user will run application code, while the group will own
59
- application specific files. Each deploying user should be added to the application group.</p>
60
-
61
- <p>This preflight recipe checks each of these things in turn, and attempts to give helpful advice
62
- should a check fail.</p>
63
- </td>
64
- <td class=code>
65
- <div class='highlight'><pre><span class="k">module</span> <span class="nn">Recap::Preflight</span>
66
- <span class="kp">extend</span> <span class="no">Recap</span><span class="o">::</span><span class="no">Namespace</span>
67
-
68
- <span class="n">namespace</span> <span class="ss">:preflight</span> <span class="k">do</span></pre></div>
69
- </td>
70
- </tr>
71
- <tr id='section-2'>
72
- <td class=docs>
73
- <div class="pilwrap">
74
- <a class="pilcrow" href="#section-2">&#182;</a>
75
- </div>
76
- <p>The preflight check is pretty quick, so run it before every <code>deploy:setup</code> and <code>deploy</code></p>
77
- </td>
78
- <td class=code>
79
- <div class='highlight'><pre> <span class="n">before</span> <span class="s1">&#39;deploy:setup&#39;</span><span class="p">,</span> <span class="s1">&#39;preflight:check&#39;</span>
80
- <span class="n">before</span> <span class="s1">&#39;deploy&#39;</span><span class="p">,</span> <span class="s1">&#39;preflight:check&#39;</span>
81
-
82
- <span class="n">set</span><span class="p">(</span><span class="ss">:remote_username</span><span class="p">)</span> <span class="p">{</span> <span class="n">capture</span><span class="p">(</span><span class="s1">&#39;whoami&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span> <span class="p">}</span>
83
-
84
- <span class="n">task</span> <span class="ss">:check</span> <span class="k">do</span></pre></div>
85
- </td>
86
- </tr>
87
- <tr id='section-3'>
88
- <td class=docs>
89
- <div class="pilwrap">
90
- <a class="pilcrow" href="#section-3">&#182;</a>
91
- </div>
92
- <p>First check the <code>application_user</code> exists</p>
93
- </td>
94
- <td class=code>
95
- <div class='highlight'><pre> <span class="k">if</span> <span class="n">exit_code</span><span class="p">(</span><span class="s2">&quot;id </span><span class="si">#{</span><span class="n">application_user</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span> <span class="o">!=</span> <span class="s2">&quot;0&quot;</span>
96
- <span class="nb">abort</span> <span class="sx">%{</span>
97
- <span class="sx">The application user &#39;</span><span class="si">#{</span><span class="n">application_user</span><span class="si">}</span><span class="sx">&#39; doesn&#39;t exist. You can create this user by logging into the server and running:</span>
98
-
99
- <span class="sx"> sudo useradd </span><span class="si">#{</span><span class="n">application_user</span><span class="si">}</span><span class="sx"></span>
100
- <span class="se">\n</span><span class="sx">}</span>
101
- <span class="k">end</span></pre></div>
102
- </td>
103
- </tr>
104
- <tr id='section-4'>
105
- <td class=docs>
106
- <div class="pilwrap">
107
- <a class="pilcrow" href="#section-4">&#182;</a>
108
- </div>
109
- <p>Then the <code>application_group</code></p>
110
- </td>
111
- <td class=code>
112
- <div class='highlight'><pre> <span class="k">if</span> <span class="n">exit_code</span><span class="p">(</span><span class="s2">&quot;id -g </span><span class="si">#{</span><span class="n">application_group</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span> <span class="o">!=</span> <span class="s2">&quot;0&quot;</span>
113
- <span class="nb">abort</span> <span class="sx">%{</span>
114
- <span class="sx">The application group &#39;</span><span class="si">#{</span><span class="n">application_group</span><span class="si">}</span><span class="sx">&#39; doesn&#39;t exist. You can create this group by logging into the server and running:</span>
115
-
116
- <span class="sx"> sudo groupadd </span><span class="si">#{</span><span class="n">application_group</span><span class="si">}</span><span class="sx"></span>
117
- <span class="sx"> sudo usermod --append -G </span><span class="si">#{</span><span class="n">application_group</span><span class="si">}</span><span class="sx"> </span><span class="si">#{</span><span class="n">application_user</span><span class="si">}</span><span class="sx"></span>
118
- <span class="se">\n</span><span class="sx">}</span>
119
- <span class="k">end</span></pre></div>
120
- </td>
121
- </tr>
122
- <tr id='section-5'>
123
- <td class=docs>
124
- <div class="pilwrap">
125
- <a class="pilcrow" href="#section-5">&#182;</a>
126
- </div>
127
- <p>Check the git configuration exists</p>
128
- </td>
129
- <td class=code>
130
- <div class='highlight'><pre> <span class="k">if</span> <span class="n">capture</span><span class="p">(</span><span class="s1">&#39;git config user.name || true&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="o">.</span><span class="n">empty?</span> <span class="o">||</span> <span class="n">capture</span><span class="p">(</span><span class="s1">&#39;git config user.email || true&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="o">.</span><span class="n">empty?</span>
131
- <span class="nb">abort</span> <span class="sx">%{</span>
132
- <span class="sx">Your remote user must have a git user.name and user.email set. You can set these by logging into the server as </span><span class="si">#{</span><span class="n">remote_username</span><span class="si">}</span><span class="sx"> and running:</span>
133
-
134
- <span class="sx"> git config --global user.email &quot;you@example.com&quot;</span>
135
- <span class="sx"> git config --global user.name &quot;Your Name&quot;</span>
136
- <span class="se">\n</span><span class="sx">}</span>
137
- <span class="k">end</span></pre></div>
138
- </td>
139
- </tr>
140
- <tr id='section-6'>
141
- <td class=docs>
142
- <div class="pilwrap">
143
- <a class="pilcrow" href="#section-6">&#182;</a>
144
- </div>
145
- <p>And finally check the remote user is a member of the <code>application_group</code></p>
146
-
147
- </td>
148
- <td class=code>
149
- <div class='highlight'><pre> <span class="k">unless</span> <span class="n">capture</span><span class="p">(</span><span class="s1">&#39;groups&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">)</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">application_group</span><span class="p">)</span>
150
- <span class="nb">abort</span> <span class="sx">%{</span>
151
- <span class="sx">Your remote user must be a member of the &#39;</span><span class="si">#{</span><span class="n">application_group</span><span class="si">}</span><span class="sx">&#39; group in order to perform deployments. You can add yourself to this group by logging into the server and running:</span>
152
-
153
- <span class="sx"> sudo usermod --append -G </span><span class="si">#{</span><span class="n">application_group</span><span class="si">}</span><span class="sx"> </span><span class="si">#{</span><span class="n">remote_username</span><span class="si">}</span><span class="sx"></span>
154
- <span class="se">\n</span><span class="sx">}</span>
155
- <span class="k">end</span>
156
- <span class="k">end</span>
157
- <span class="k">end</span>
158
- <span class="k">end</span></pre></div>
159
- </td>
160
- </tr>
161
- </table>
162
- </div>
163
- </body>
@@ -1,42 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
- <title>rails.rb</title>
6
- <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
- </head>
8
- <body>
9
- <div id='container'>
10
- <div id="background"></div>
11
- <div id="jump_to">
12
- Jump To &hellip;
13
- <div id="jump_wrapper">
14
- <div id="jump_page">
15
- <a class="source" href="../../index.html">index.rb</a>
16
- <a class="source" href="../recap.html">recap.rb</a>
17
- <a class="source" href="bootstrap.html">bootstrap.rb</a>
18
- <a class="source" href="bundler.html">bundler.rb</a>
19
- <a class="source" href="capistrano_extensions.html">capistrano_extensions.rb</a>
20
- <a class="source" href="cli.html">cli.rb</a>
21
- <a class="source" href="compatibility.html">compatibility.rb</a>
22
- <a class="source" href="deploy.html">deploy.rb</a>
23
- <a class="source" href="env.html">env.rb</a>
24
- <a class="source" href="foreman.html">foreman.rb</a>
25
- <a class="source" href="namespace.html">namespace.rb</a>
26
- <a class="source" href="preflight.html">preflight.rb</a>
27
- <a class="source" href="rails.html">rails.rb</a>
28
- <a class="source" href="version.html">version.rb</a>
29
- </div>
30
- </div>
31
- </div>
32
- <table cellspacing=0 cellpadding=0>
33
- <thead>
34
- <tr>
35
- <th class=docs><h1>rails.rb</h1></th>
36
- <th class=code></th>
37
- </tr>
38
- </thead>
39
- <tbody>
40
- </table>
41
- </div>
42
- </body>
@@ -1,42 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
- <title>version.rb</title>
6
- <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
- </head>
8
- <body>
9
- <div id='container'>
10
- <div id="background"></div>
11
- <div id="jump_to">
12
- Jump To &hellip;
13
- <div id="jump_wrapper">
14
- <div id="jump_page">
15
- <a class="source" href="../../index.html">index.rb</a>
16
- <a class="source" href="../recap.html">recap.rb</a>
17
- <a class="source" href="bootstrap.html">bootstrap.rb</a>
18
- <a class="source" href="bundler.html">bundler.rb</a>
19
- <a class="source" href="capistrano_extensions.html">capistrano_extensions.rb</a>
20
- <a class="source" href="cli.html">cli.rb</a>
21
- <a class="source" href="compatibility.html">compatibility.rb</a>
22
- <a class="source" href="deploy.html">deploy.rb</a>
23
- <a class="source" href="env.html">env.rb</a>
24
- <a class="source" href="foreman.html">foreman.rb</a>
25
- <a class="source" href="namespace.html">namespace.rb</a>
26
- <a class="source" href="preflight.html">preflight.rb</a>
27
- <a class="source" href="rails.html">rails.rb</a>
28
- <a class="source" href="version.html">version.rb</a>
29
- </div>
30
- </div>
31
- </div>
32
- <table cellspacing=0 cellpadding=0>
33
- <thead>
34
- <tr>
35
- <th class=docs><h1>version.rb</h1></th>
36
- <th class=code></th>
37
- </tr>
38
- </thead>
39
- <tbody>
40
- </table>
41
- </div>
42
- </body>
data/doc/lib/recap.html DELETED
@@ -1,42 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
- <title>recap.rb</title>
6
- <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
- </head>
8
- <body>
9
- <div id='container'>
10
- <div id="background"></div>
11
- <div id="jump_to">
12
- Jump To &hellip;
13
- <div id="jump_wrapper">
14
- <div id="jump_page">
15
- <a class="source" href="../index.html">index.rb</a>
16
- <a class="source" href="recap.html">recap.rb</a>
17
- <a class="source" href="recap/bootstrap.html">bootstrap.rb</a>
18
- <a class="source" href="recap/bundler.html">bundler.rb</a>
19
- <a class="source" href="recap/capistrano_extensions.html">capistrano_extensions.rb</a>
20
- <a class="source" href="recap/cli.html">cli.rb</a>
21
- <a class="source" href="recap/compatibility.html">compatibility.rb</a>
22
- <a class="source" href="recap/deploy.html">deploy.rb</a>
23
- <a class="source" href="recap/env.html">env.rb</a>
24
- <a class="source" href="recap/foreman.html">foreman.rb</a>
25
- <a class="source" href="recap/namespace.html">namespace.rb</a>
26
- <a class="source" href="recap/preflight.html">preflight.rb</a>
27
- <a class="source" href="recap/rails.html">rails.rb</a>
28
- <a class="source" href="recap/version.html">version.rb</a>
29
- </div>
30
- </div>
31
- </div>
32
- <table cellspacing=0 cellpadding=0>
33
- <thead>
34
- <tr>
35
- <th class=docs><h1>recap.rb</h1></th>
36
- <th class=code></th>
37
- </tr>
38
- </thead>
39
- <tbody>
40
- </table>
41
- </div>
42
- </body>
data/index.rb DELETED
@@ -1,62 +0,0 @@
1
- # This is the annotated source code and documentation for
2
- # [recap](http://github.com/freerange/recap), a simple, opinionated set of capistrano
3
- # deployment recipes.
4
-
5
- # Inspired in part by
6
- # [this blog post](https://github.com/blog/470-deployment-script-spring-cleaning), these recipes use
7
- # git's strengths to deploy applications in a faster, simpler manner than a standard capistrano
8
- # deployment. Using git to manage release versions means apps can be deployed to a single directory.
9
- # There's no need for `releases`, `shared` or `current` folders, and no symlinking.
10
-
11
- # ### Goals ###
12
-
13
- # These deployment recipes try to do the following:
14
-
15
- # Where possible run commands as the `application_user`, loading the full user environment. The only
16
- # exceptions are `git` commands (which often rely on SSH agent forwarding for authentication), and
17
- # anything that requires `sudo`.
18
- #
19
-
20
- # Use `git` to avoid unecessary work. If the `Gemfile.lock` hasn't changed, there's no need to run
21
- # `bundle install`. Similarly if there are no new migrations, why do `rake db:migrate`? Faster
22
- # deploys mean more frequent deploys.
23
- #
24
-
25
- # Avoid the use of `sudo` (other than to change to the `application_user`). As much as possible,
26
- # `sudo` is only used to `su` to the `application_user` before running a command. To avoid having to
27
- # type a password to perform the majority of deployment tasks, these lines can be added to
28
- # `/etc/sudoers.d/application` (change `application` to the name of your app).
29
-
30
- %application ALL=NOPASSWD: /sbin/start application*
31
- %application ALL=NOPASSWD: /sbin/stop application*
32
- %application ALL=NOPASSWD: /sbin/restart application*
33
- %application ALL=NOPASSWD: /bin/su - application*
34
- %application ALL=NOPASSWD: /bin/su application*
35
-
36
- # Use environment variables for configuration. Rather than setting `rails_env` in the `Capfile`,
37
- # `RAILS_ENV` (or `RACK_ENV`) variables should be set for the `application_user`. The `env:set` and
38
- # `env:edit` tasks help do this.
39
-
40
- # ### Code layout ###
41
-
42
- # The main deployment tasks are defined in [recap/deploy.rb](lib/recap/deploy.html). Automatic
43
- # checks to ensure servers are correctly setup are in
44
- # [recap/preflight.rb](lib/recap/preflight.html), while tasks for environment variables are in
45
- # [recap/env.rb](lib/recap/env.html)
46
-
47
- # In addition, there are extensions for [bundler](lib/recap/bundler.html),
48
- # [foreman](lib/recap/foreman.html) and [rails](lib/recap/rails.html)
49
-
50
- # For limited compatability with other existing recipes, see
51
- # [compatibility](lib/recap/compatibility.html).
52
-
53
- # ### Deployment target ###
54
-
55
- # These recipes have been developed and tested using Ubuntu 11.04, though they may work well with
56
- # other flavours of unix.
57
-
58
- # The application should be run as the application user; if using Apache and Passenger, you should
59
- # set the `PassengerDefaultUser` directive to be the same as the `application_user`.
60
-
61
- # The code is available [on github](http://github.com/freerange/recap) and released under the
62
- # [MIT License](https://github.com/freerange/recap/blob/master/LICENSE)
@@ -1,47 +0,0 @@
1
- module Recap::Bootstrap
2
- extend Recap::Namespace
3
-
4
- namespace :bootstrap do
5
- set(:remote_username) { capture('whoami').strip }
6
- set(:application_home) { "/home/#{application_user}"}
7
-
8
- task :default do
9
- application
10
- user
11
- end
12
-
13
- task :application do
14
- if exit_code("id #{application_user}").strip != "0"
15
- sudo "useradd #{application_user} -d #{application_home}"
16
- end
17
- sudo "mkdir -p #{application_home}"
18
- sudo "chown #{application_user}:#{application_group} #{application_home}"
19
- sudo "chmod 755 #{application_home}"
20
-
21
- put_as_app %{
22
- if [ -s "$HOME/.env" ]; then
23
- rm -rf $HOME/.recap-env-export
24
- touch $HOME/.recap-env-export
25
- while read line
26
- do echo "export $line" >> $HOME/.recap-env-export;
27
- done < $HOME/.env
28
- . $HOME/.recap-env-export
29
- fi
30
- }, "#{application_home}/.recap"
31
-
32
- as_app "touch .profile", "~"
33
-
34
- if exit_code(%{grep '\\. \\$HOME\\/.recap' .profile}) != "0"
35
- as_app %{echo >> .profile && echo ". \\$HOME/.recap" >> .profile}, "~"
36
- end
37
-
38
- as_app "mkdir -p #{deploy_to}", "~"
39
- end
40
-
41
- task :user do
42
- run "git config --global user.name '#{`git config user.name`.strip}'"
43
- run "git config --global user.email '#{`git config user.email`.strip}'"
44
- sudo "usermod --append -G #{application_group} #{remote_username}"
45
- end
46
- end
47
- end
@@ -1,74 +0,0 @@
1
- require 'tempfile'
2
-
3
- module Recap
4
- module CapistranoExtensions
5
- # Run a command as the given user
6
- def as_user(user, command, pwd = deploy_to)
7
- sudo "su - #{user} -c 'cd #{pwd} && #{command}'"
8
- end
9
-
10
- # Run a command as root
11
- def as_root(command, pwd = deploy_to)
12
- as_user 'root', command, pwd
13
- end
14
-
15
- # Run a command as the application user
16
- def as_app(command, pwd = deploy_to)
17
- as_user application_user, command, pwd
18
- end
19
-
20
- # Put a string into a file as the application user
21
- def put_as_app(string, path)
22
- put string, "/tmp/recap-put-as-app"
23
- as_app "cp /tmp/recap-put-as-app #{path} && chmod g+rw #{path}", "/"
24
- end
25
-
26
- # Edit a file on the remote server, using a local editor
27
- def edit_file(path)
28
- if editor = ENV['DEPLOY_EDITOR'] || ENV['EDITOR']
29
- as_app "touch #{path} && chmod g+rw #{path}"
30
- local_path = Tempfile.new('deploy-edit').path
31
- get(path, local_path)
32
- `#{editor} #{local_path}`
33
- upload(local_path, path)
34
- else
35
- abort "To edit a remote file, either the EDITOR or DEPLOY_EDITOR environment variables must be set"
36
- end
37
- end
38
-
39
- # Run a git command in the `deploy_to` directory
40
- def git(command)
41
- run "cd #{deploy_to} && umask 002 && sg #{application_group} -c \"git #{command}\""
42
- end
43
-
44
- # Capture the result of a git command run within the `deploy_to` directory
45
- def capture_git(command)
46
- capture "cd #{deploy_to} && umask 002 && sg #{application_group} -c 'git #{command}'"
47
- end
48
-
49
- def exit_code(command)
50
- capture("#{command} > /dev/null 2>&1; echo $?").strip
51
- end
52
-
53
- # Find the latest tag from the repository. As `git tag` returns tags in order, and our release
54
- # tags are timestamps, the latest tag will always be the last in the list.
55
- def latest_tag_from_repository
56
- result = capture_git("tag | tail -n1").strip
57
- result.empty? ? nil : result
58
- end
59
-
60
- # Does the given file exist within the deployment directory?
61
- def deployed_file_exists?(path)
62
- exit_code("cd #{deploy_to} && [ -f #{path} ]") == "0"
63
- end
64
-
65
- # Has the given path been created or changed since the previous deployment? During the first
66
- # successful deployment this will always return true.
67
- def deployed_file_changed?(path)
68
- return true unless latest_tag
69
- exit_code("cd #{deploy_to} && git diff --exit-code #{latest_tag} origin/#{branch} #{path}") == "1"
70
- end
71
-
72
- Capistrano::Configuration.send :include, self
73
- end
74
- end
data/lib/recap/cli.rb DELETED
@@ -1,32 +0,0 @@
1
- require 'thor'
2
-
3
- module Recap
4
- class CLI < Thor
5
- include Thor::Actions
6
-
7
- attr_accessor :name, :repository
8
-
9
- def self.source_root
10
- File.expand_path("../deploy/templates", __FILE__)
11
- end
12
-
13
- desc 'setup', 'Setup basic capistrano recipes, e.g: recap setup'
14
- method_option :name, :aliases => "-n"
15
- method_option :repository, :aliases => "-r"
16
- def setup
17
- self.name = options["name"] || guess_name
18
- self.repository = options["repo"] || guess_repository
19
- template 'Capfile.erb', 'Capfile'
20
- end
21
-
22
- private
23
-
24
- def guess_name
25
- Dir.pwd.split(File::SEPARATOR).last
26
- end
27
-
28
- def guess_repository
29
- `git remote -v`.split[1]
30
- end
31
- end
32
- end
@@ -1,6 +0,0 @@
1
- require "recap/deploy"
2
-
3
- set :application, "<%= name %>"
4
-
5
- set :repository, "<%= repository %>"
6
- set :branch, "master"
data/lib/recap/env.rb DELETED
@@ -1,58 +0,0 @@
1
- # Environment variables are a useful way to set application configuration, such as database passwords
2
- # or S3 keys and secrets. [recap](http://github.com/freerange/recap) stores these extra variables in
3
- # a special file, usually stored at `$HOME/.env`. This file is loaded each time the shell starts by
4
- # adding the following to the user's `.profile`:
5
- #
6
- # . $HOME/.recap
7
- #
8
- # The `.recap` script is automatically generated in the bootstrap process.
9
-
10
- module Recap::Env
11
- extend Recap::Namespace
12
-
13
- namespace :env do
14
- # Environment
15
- set(:environment_file) { "/home/#{application_user}/.env" }
16
-
17
- def current_environment
18
- @current_environment ||= begin
19
- if deployed_file_exists?(environment_file)
20
- Recap::Environment.from_string(capture("cat #{environment_file}"))
21
- else
22
- Recap::Environment.new
23
- end
24
- end
25
- end
26
-
27
- task :default do
28
- if current_environment.empty?
29
- puts "There are no config variables set"
30
- else
31
- puts "The config variables are:"
32
- puts
33
- puts current_environment
34
- end
35
- end
36
-
37
- task :set do
38
- env = ARGV[1..-1].inject(current_environment) do |env, string|
39
- env.set_string(string)
40
- logger.debug "Setting #{string}"
41
- logger.debug "Env is now: #{env}"
42
- env
43
- end
44
-
45
- if env.empty?
46
- as_app "rm -f #{environment_file}", "~"
47
- else
48
- put_as_app env.to_s, environment_file
49
- end
50
- default
51
- end
52
-
53
- task :edit do
54
- edit_file environment_file
55
- default
56
- end
57
- end
58
- end
@@ -1,54 +0,0 @@
1
- class Recap::Environment
2
- def initialize(variables = {})
3
- @variables = variables
4
- end
5
-
6
- def get(name)
7
- @variables[name]
8
- end
9
-
10
- def set(name, value)
11
- if value.nil? || value.empty?
12
- @variables.delete(name)
13
- else
14
- @variables[name] = value
15
- end
16
- end
17
-
18
- def set_string(string)
19
- if string =~ /\A([A-Za-z0-9_]+)=(.*)\z/
20
- set $1, $2
21
- end
22
- end
23
-
24
- def empty?
25
- @variables.empty?
26
- end
27
-
28
- def merge(hash)
29
- hash.each {|k, v| set(k, v)}
30
- end
31
-
32
- def each(&block)
33
- @variables.sort.each(&block)
34
- end
35
-
36
- def include?(key)
37
- @variables.include?(key)
38
- end
39
-
40
- def to_s
41
- @variables.keys.sort.map do |key|
42
- key + "=" + @variables[key] + "\n" if @variables[key]
43
- end.compact.join
44
- end
45
-
46
- class << self
47
- def from_string(string)
48
- string.split("\n").inject(new) do |env, line|
49
- env.set_string(line)
50
- env
51
- end
52
- end
53
- end
54
- end