capitate 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +5 -0
- data/Manifest.txt +2 -0
- data/lib/capitate/plugins/base.rb +7 -0
- data/lib/capitate/plugins/upload.rb +58 -0
- data/lib/capitate/task_node.rb +62 -4
- data/lib/capitate/version.rb +1 -1
- data/lib/capitate.rb +2 -0
- data/lib/recipes/docs.rb +0 -2
- data/lib/recipes/mongrel_cluster.rb +22 -1
- data/lib/templates/mongrel/mongrel_cluster.yml.erb +1 -0
- data/lib/templates/nginx/nginx.conf.erb +8 -0
- data/script/txt2html +31 -25
- data/tasks/website.rake +3 -6
- data/test/test_plugin_upload.rb +32 -0
- data/website/index.html +5 -6
- data/website/index.txt +3 -4
- metadata +5 -2
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -17,6 +17,7 @@ lib/capitate/plugins/package.rb
|
|
17
17
|
lib/capitate/plugins/profiles.rb
|
18
18
|
lib/capitate/plugins/script.rb
|
19
19
|
lib/capitate/plugins/templates.rb
|
20
|
+
lib/capitate/plugins/upload.rb
|
20
21
|
lib/capitate/plugins/wget.rb
|
21
22
|
lib/capitate/plugins/yum.rb
|
22
23
|
lib/capitate/recipes.rb
|
@@ -77,6 +78,7 @@ tasks/deployment.rake
|
|
77
78
|
tasks/environment.rake
|
78
79
|
tasks/website.rake
|
79
80
|
test/test_helper.rb
|
81
|
+
test/test_plugin_upload.rb
|
80
82
|
test/test_recipes.rb
|
81
83
|
test/test_templates.rb
|
82
84
|
website/index.html
|
@@ -1,3 +1,10 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2007, Gabriel Handford (gabrielh@gmail.com)
|
4
|
+
# All rights reserved.
|
5
|
+
# =============================================================================
|
6
|
+
#++
|
7
|
+
|
1
8
|
require 'erb'
|
2
9
|
require 'yaml'
|
3
10
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Capitate::Plugins::Upload
|
2
|
+
|
3
|
+
# Upload file with source path.
|
4
|
+
# Data is streamed.
|
5
|
+
#
|
6
|
+
# ==== Options
|
7
|
+
# +src_path+:: Source path
|
8
|
+
# +dest_path:: Remote destination path
|
9
|
+
# +options+:: Options (see capistrano 'put')
|
10
|
+
#
|
11
|
+
def file(src_path, dest_path, options = {})
|
12
|
+
data = FileData.new(src_path)
|
13
|
+
put(data, dest_path, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Stream data with Net::SFTP by looking like an Array
|
17
|
+
class FileData
|
18
|
+
|
19
|
+
def initialize(path)
|
20
|
+
@path = path
|
21
|
+
@next_start = 0
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](start, length)
|
25
|
+
|
26
|
+
if start != @next_start
|
27
|
+
raise <<-EOS
|
28
|
+
|
29
|
+
Can only access data sequentially; so we can stream it (The next start position should have been: #{@next_start})
|
30
|
+
|
31
|
+
EOS
|
32
|
+
end
|
33
|
+
|
34
|
+
data = file.read(length)
|
35
|
+
|
36
|
+
@next_start = start + length
|
37
|
+
close if @next_start >= self.length
|
38
|
+
|
39
|
+
data
|
40
|
+
end
|
41
|
+
|
42
|
+
def length
|
43
|
+
@file_size ||= File.size(@path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def file
|
47
|
+
@file ||= File.open(@path, "r")
|
48
|
+
end
|
49
|
+
|
50
|
+
def close
|
51
|
+
@file.close if @file
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
Capistrano.plugin :upload, Capitate::Plugins::Upload
|
data/lib/capitate/task_node.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
#
|
1
|
+
# Task node in the capistrano namespace, task hierarchy.
|
2
|
+
#
|
2
3
|
class Capitate::TaskNode
|
3
4
|
|
4
5
|
include Capitate::Plugins::Base
|
5
6
|
|
6
7
|
attr_reader :name, :nodes, :tasks, :parent
|
7
|
-
|
8
|
+
|
9
|
+
# Create task node with name and parent
|
10
|
+
# For root not use name = "top"
|
11
|
+
#
|
12
|
+
# ==== Options
|
13
|
+
# +name+:: Node name (namespace name)
|
14
|
+
# +parent+:: Parent node
|
15
|
+
#
|
8
16
|
def initialize(name, parent = nil)
|
9
17
|
@name = name
|
10
18
|
@parent = parent
|
@@ -12,10 +20,20 @@ class Capitate::TaskNode
|
|
12
20
|
@tasks = []
|
13
21
|
end
|
14
22
|
|
23
|
+
# Add "child" node.
|
24
|
+
#
|
25
|
+
# ==== Options
|
26
|
+
# +task_node+:: Node
|
27
|
+
#
|
15
28
|
def add_node(task_node)
|
16
29
|
@nodes << task_node
|
17
30
|
end
|
18
31
|
|
32
|
+
# Find node with name (namespace).
|
33
|
+
#
|
34
|
+
# ==== Options
|
35
|
+
# +name+:: Name to look for
|
36
|
+
#
|
19
37
|
def find(name)
|
20
38
|
@nodes.each do |node|
|
21
39
|
return node if node.name == name
|
@@ -23,15 +41,27 @@ class Capitate::TaskNode
|
|
23
41
|
nil
|
24
42
|
end
|
25
43
|
|
44
|
+
# Add task to this node.
|
45
|
+
#
|
46
|
+
# ==== Options
|
47
|
+
# +task+:: Add task associated with this node (namespace).
|
48
|
+
#
|
26
49
|
def add_task(task)
|
27
50
|
@tasks << task
|
28
51
|
end
|
29
52
|
|
53
|
+
# Get "child" nodes (sorted).
|
54
|
+
#
|
30
55
|
def sorted_nodes
|
31
56
|
nodes.sort_by(&:name)
|
32
57
|
end
|
33
58
|
|
34
|
-
#
|
59
|
+
# Iterate over ALL "child" nodes, depth first.
|
60
|
+
# Yields |node, level|.
|
61
|
+
#
|
62
|
+
# ==== Options
|
63
|
+
# +level+:: Current level
|
64
|
+
#
|
35
65
|
def each_node(level = 0, &block)
|
36
66
|
sorted_nodes.each do |node|
|
37
67
|
yield(node, level)
|
@@ -39,6 +69,14 @@ class Capitate::TaskNode
|
|
39
69
|
end
|
40
70
|
end
|
41
71
|
|
72
|
+
# Get the full name, using delimeter
|
73
|
+
#
|
74
|
+
# ==== Options
|
75
|
+
# +delimeter+:: Delimeter
|
76
|
+
#
|
77
|
+
# ==== Examples
|
78
|
+
# node.full_name(":") => "mysql:centos" # On node mysql centos node (top -> mysql -> centos)
|
79
|
+
#
|
42
80
|
def full_name(delimeter = "-")
|
43
81
|
if parent
|
44
82
|
parent_name = parent.full_name
|
@@ -50,6 +88,13 @@ class Capitate::TaskNode
|
|
50
88
|
end
|
51
89
|
|
52
90
|
# Write doc for node (recursively)
|
91
|
+
#
|
92
|
+
# ==== Options
|
93
|
+
# +dir+:: Dir to write to
|
94
|
+
# +file_name+:: File name to write to, defaults to full name
|
95
|
+
# +title+:: Title and h1 for page, defaults to name
|
96
|
+
# +options+:: Options
|
97
|
+
#
|
53
98
|
def write_doc(dir, file_name = nil, title = nil, options = {}, &block)
|
54
99
|
|
55
100
|
file_name ||= full_name
|
@@ -115,6 +160,8 @@ class Capitate::TaskNode
|
|
115
160
|
end
|
116
161
|
end
|
117
162
|
|
163
|
+
# Node to string.
|
164
|
+
#
|
118
165
|
def to_s(level = 0)
|
119
166
|
spaces = " "
|
120
167
|
indent = (0...level).collect { spaces }.join("")
|
@@ -133,9 +180,20 @@ class Capitate::TaskNode
|
|
133
180
|
end
|
134
181
|
s
|
135
182
|
end
|
136
|
-
|
183
|
+
|
184
|
+
# Class methods
|
137
185
|
class << self
|
138
186
|
|
187
|
+
# Create nodes and and task to node.
|
188
|
+
#
|
189
|
+
# If task is "mysql:centos:install", the nodes will look like:
|
190
|
+
#
|
191
|
+
# (top node) -> (mysql node) -> (centos node; w/ tasks: install)
|
192
|
+
#
|
193
|
+
# ==== Options
|
194
|
+
# +top_node+:: Node to start at
|
195
|
+
# +task+:: Task to add
|
196
|
+
#
|
139
197
|
def populate_with_task(top_node, task)
|
140
198
|
node_names = task.namespace.fully_qualified_name.split(":")
|
141
199
|
|
data/lib/capitate/version.rb
CHANGED
data/lib/capitate.rb
CHANGED
@@ -22,6 +22,8 @@ require 'capitate/plugins/templates'
|
|
22
22
|
require 'capitate/plugins/wget'
|
23
23
|
require 'capitate/plugins/yum'
|
24
24
|
|
25
|
+
require 'capitate/plugins/upload'
|
26
|
+
|
25
27
|
require "capitate/cap_ext/connections"
|
26
28
|
require "capitate/cap_ext/extension_proxy"
|
27
29
|
require "capitate/cap_ext/variables"
|
data/lib/recipes/docs.rb
CHANGED
@@ -13,6 +13,10 @@ namespace :mongrel_cluster do
|
|
13
13
|
|
14
14
|
set :mongrel_port, 9000
|
15
15
|
|
16
|
+
mongrel_config_script: Config script to load with mongrel.
|
17
|
+
|
18
|
+
set :mongrel_config_script, "config/mongrel_handler.rb"
|
19
|
+
|
16
20
|
DESC
|
17
21
|
task :setup_monit do
|
18
22
|
|
@@ -24,13 +28,30 @@ namespace :mongrel_cluster do
|
|
24
28
|
# Settings
|
25
29
|
fetch(:mongrel_size)
|
26
30
|
fetch(:mongrel_port)
|
31
|
+
fetch_or_default(:mongrel_config_script, nil)
|
27
32
|
|
28
33
|
processes = []
|
29
34
|
ports = (0...mongrel_size).collect { |i| mongrel_port + i }
|
30
35
|
ports.each do |port|
|
31
36
|
|
32
37
|
pid_path = "#{shared_path}/pids/mongrel.#{port}.pid"
|
33
|
-
|
38
|
+
|
39
|
+
default_options = [
|
40
|
+
[ "-d" ],
|
41
|
+
[ "-e", "production" ],
|
42
|
+
[ "-a", "127.0.0.1" ],
|
43
|
+
[ "-c", current_path ],
|
44
|
+
[ "--user", user ],
|
45
|
+
[ "--group", user ],
|
46
|
+
[ "-p", port ],
|
47
|
+
[ "-P", pid_path ],
|
48
|
+
[ "-l", "log/mongrel.#{port}.log" ]
|
49
|
+
]
|
50
|
+
|
51
|
+
default_options << [ "-S", mongrel_config_script ] if mongrel_config_script
|
52
|
+
|
53
|
+
start_options = default_options.collect { |a| a.join(" ") }.join(" ")
|
54
|
+
#start_options = "-d -e production -a 127.0.0.1 -c #{current_path} --user #{user} --group #{user} -p #{port} -P #{pid_path} -l log/mongrel.#{port}.log"
|
34
55
|
stop_options = "-p #{port} -P #{pid_path}"
|
35
56
|
|
36
57
|
processes << { :port => port, :start_options => start_options, :stop_options => stop_options, :name => "/usr/bin/mongrel_rails", :pid_path => pid_path }
|
@@ -4,10 +4,18 @@
|
|
4
4
|
# See vhost conf for site specific stuff.
|
5
5
|
#
|
6
6
|
# ==== References:
|
7
|
+
# http://brainspl.at/articles/2006/08/23/nginx-my-new-favorite-front-end-for-mongrel-cluster
|
7
8
|
# http://brainspl.at/articles/2007/01/03/new-nginx-conf-with-optimizations
|
8
9
|
# http://topfunky.net/svn/shovel/nginx
|
9
10
|
# http://robsanheim.com/2008/02/07/beware-the-default-nginx-config-old-ie6-hates-gzip/
|
10
11
|
#
|
12
|
+
# Nginx + memcached:
|
13
|
+
# http://www.igvita.com/2008/02/11/nginx-and-memcached-a-400-boost/
|
14
|
+
# http://blog.kovyrin.net/2007/08/05/using-nginx-ssi-and-memcache-to-make-your-web-applications-faster/
|
15
|
+
#
|
16
|
+
# Fair balancing:
|
17
|
+
# http://brainspl.at/articles/2007/11/09/a-fair-proxy-balancer-for-nginx-and-mongrel
|
18
|
+
|
11
19
|
|
12
20
|
# user and group to run as
|
13
21
|
user nginx nginx;
|
data/script/txt2html
CHANGED
@@ -40,35 +40,41 @@ def convert_syntax(syntax, source)
|
|
40
40
|
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
41
41
|
end
|
42
42
|
|
43
|
-
if ARGV.length >=
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
if ARGV.length >= 3
|
44
|
+
src_glob, template, output_dir = ARGV
|
45
|
+
src_files = Dir[src_glob]
|
47
46
|
else
|
48
|
-
puts("Usage: #{File.split($0).last} source
|
47
|
+
puts("Usage: #{File.split($0).last} path/to/source*.txt template.rhtml output_dir")
|
49
48
|
exit!
|
50
49
|
end
|
51
50
|
|
52
51
|
template = ERB.new(File.open(template).read)
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
53
|
+
src_files.each do |src|
|
54
|
+
title = nil
|
55
|
+
body = nil
|
56
|
+
File.open(src) do |fsrc|
|
57
|
+
title_text = fsrc.readline
|
58
|
+
body_text = fsrc.read
|
59
|
+
syntax_items = []
|
60
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
61
|
+
ident = syntax_items.length
|
62
|
+
element, syntax, source = $1, $2, $3
|
63
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
64
|
+
"syntax-temp-#{ident}"
|
65
|
+
}
|
66
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
67
|
+
body = RedCloth.new(body_text).to_html
|
68
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
69
|
+
end
|
70
|
+
stat = File.stat(src)
|
71
|
+
created = stat.ctime
|
72
|
+
modified = stat.mtime
|
73
73
|
|
74
|
-
|
74
|
+
#$stdout << template.result(binding)
|
75
|
+
output_file_path = src.split("/").last.gsub(/txt$/, "html")
|
76
|
+
output_path = output_dir + "/" + output_file_path
|
77
|
+
puts " create #{output_path}"
|
78
|
+
File.open(output_path, "w") { |file| file.puts template.result(binding) }
|
79
|
+
|
80
|
+
end
|
data/tasks/website.rake
CHANGED
@@ -1,17 +1,14 @@
|
|
1
1
|
desc 'Generate website files'
|
2
2
|
task :website_generate => :ruby_env do
|
3
|
-
(
|
4
|
-
|
5
|
-
end
|
3
|
+
template = File.join(File.dirname(__FILE__), '/../website/template.rhtml')
|
4
|
+
sh %{ #{RUBY_APP} script/txt2html "website/**/*.txt" #{template} website }
|
6
5
|
|
7
6
|
# Clean and re-create
|
8
7
|
FileUtils.rm_rf("website/recipes")
|
9
8
|
FileUtils.mkdir_p("website/recipes")
|
10
9
|
sh "cap docs:recipes"
|
11
10
|
template = File.join(File.dirname(__FILE__), '/../website/template_recipe.rhtml')
|
12
|
-
|
13
|
-
sh %{ #{RUBY_APP} script/txt2html #{txt} #{template} > website/recipes/#{txt.split("/").last.gsub(/txt$/,'html')} }
|
14
|
-
end
|
11
|
+
sh %{ #{RUBY_APP} script/txt2html "docs/recipes/**/*.txt" #{template} website/recipes }
|
15
12
|
end
|
16
13
|
|
17
14
|
desc 'Upload website files to rubyforge'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestPluginUpload < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Capitate::Plugins::Upload
|
6
|
+
|
7
|
+
# Mocked put
|
8
|
+
def put(data, dest_path, options)
|
9
|
+
start = 0
|
10
|
+
length = 4096
|
11
|
+
|
12
|
+
@mock_put << data[start, length]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Test upload streamed
|
16
|
+
def test_upload
|
17
|
+
@mock_put = ""
|
18
|
+
|
19
|
+
# Use this file for data
|
20
|
+
path = __FILE__
|
21
|
+
|
22
|
+
file(path, "mocked")
|
23
|
+
|
24
|
+
data = nil
|
25
|
+
File.open(__FILE__) { |f| data = f.readlines }
|
26
|
+
data = data.join
|
27
|
+
|
28
|
+
assert_equal data, @mock_put
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
data/website/index.html
CHANGED
@@ -38,7 +38,7 @@
|
|
38
38
|
|
39
39
|
<div id="version" class="clickable box" onclick='document.location = "http://rubyforge.org/projects/capitate"; return false'>
|
40
40
|
<p>Get Version</p>
|
41
|
-
<a href="http://rubyforge.org/projects/capitate" class="numbers">0.1.
|
41
|
+
<a href="http://rubyforge.org/projects/capitate" class="numbers">0.1.9</a>
|
42
42
|
</div>
|
43
43
|
|
44
44
|
<div id="recipes" class="box">
|
@@ -65,10 +65,9 @@
|
|
65
65
|
<p>Add capitate to your Capfile. Copy this somewhere near the top:</p>
|
66
66
|
|
67
67
|
|
68
|
-
<p><pre class='syntax'>
|
69
|
-
|
70
|
-
|
71
|
-
<span class="ident">require</span> <span class="punct">'</span><span class="string">capitate/recipes</span><span class="punct">'</span>
|
68
|
+
<p><pre class='syntax'><span class="ident">require</span> <span class="punct">'</span><span class="string">capitate</span><span class="punct">'</span>
|
69
|
+
<span class="ident">require</span> <span class="punct">'</span><span class="string">capitate/recipes</span><span class="punct">'</span>
|
70
|
+
<span class="ident">set</span> <span class="symbol">:project_root</span><span class="punct">,</span> <span class="constant">File</span><span class="punct">.</span><span class="ident">dirname</span><span class="punct">(</span><span class="constant">__FILE__</span><span class="punct">)</span>
|
72
71
|
</pre></p>
|
73
72
|
|
74
73
|
|
@@ -152,7 +151,7 @@
|
|
152
151
|
<p>Comments are welcome. Send an email to <a href="mailto:gabrielh@gmail.com">Gabriel Handford</a> via the <a href="http://groups.google.com/group/capitate">forum</a></p>
|
153
152
|
</div>
|
154
153
|
<p class="coda">
|
155
|
-
<a href="FIXME email">Gabriel Handford</a>,
|
154
|
+
<a href="FIXME email">Gabriel Handford</a>, 22nd February 2008<br>
|
156
155
|
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
157
156
|
</p>
|
158
157
|
</div>
|
data/website/index.txt
CHANGED
@@ -13,10 +13,9 @@ h2. Running
|
|
13
13
|
|
14
14
|
Add capitate to your Capfile. Copy this somewhere near the top:
|
15
15
|
|
16
|
-
<pre syntax="ruby">
|
17
|
-
|
18
|
-
|
19
|
-
require 'capitate/recipes'
|
16
|
+
<pre syntax="ruby">require 'capitate'
|
17
|
+
require 'capitate/recipes'
|
18
|
+
set :project_root, File.dirname(__FILE__)
|
20
19
|
</pre>
|
21
20
|
|
22
21
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capitate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ""
|
6
6
|
authors:
|
7
7
|
- Gabriel Handford
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-22 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -54,6 +54,7 @@ files:
|
|
54
54
|
- lib/capitate/plugins/profiles.rb
|
55
55
|
- lib/capitate/plugins/script.rb
|
56
56
|
- lib/capitate/plugins/templates.rb
|
57
|
+
- lib/capitate/plugins/upload.rb
|
57
58
|
- lib/capitate/plugins/wget.rb
|
58
59
|
- lib/capitate/plugins/yum.rb
|
59
60
|
- lib/capitate/recipes.rb
|
@@ -114,6 +115,7 @@ files:
|
|
114
115
|
- tasks/environment.rake
|
115
116
|
- tasks/website.rake
|
116
117
|
- test/test_helper.rb
|
118
|
+
- test/test_plugin_upload.rb
|
117
119
|
- test/test_recipes.rb
|
118
120
|
- test/test_templates.rb
|
119
121
|
- website/index.html
|
@@ -151,5 +153,6 @@ specification_version: 2
|
|
151
153
|
summary: Capistrano recipes, plugins and templates.
|
152
154
|
test_files:
|
153
155
|
- test/test_helper.rb
|
156
|
+
- test/test_plugin_upload.rb
|
154
157
|
- test/test_recipes.rb
|
155
158
|
- test/test_templates.rb
|