god 0.7.13 → 0.7.14
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/.gitignore +8 -0
- data/Announce.txt +135 -0
- data/History.txt +15 -0
- data/Rakefile +44 -11
- data/VERSION.yml +4 -0
- data/ext/god/.gitignore +5 -0
- data/ext/god/netlink_handler.c +1 -0
- data/god.gemspec +223 -0
- data/ideas/execve/execve.c +29 -0
- data/ideas/execve/extconf.rb +11 -0
- data/ideas/execve/go.rb +8 -0
- data/ideas/future.god +82 -0
- data/init/lsb_compliant_god +109 -0
- data/lib/god.rb +6 -3
- data/lib/god/cli/command.rb +2 -1
- data/lib/god/cli/version.rb +2 -2
- data/lib/god/contacts/campfire.rb +3 -2
- data/lib/god/contacts/jabber.rb +82 -20
- data/lib/god/logger.rb +5 -1
- data/lib/god/process.rb +0 -6
- data/site/images/banner.jpg +0 -0
- data/site/images/bg.gif +0 -0
- data/site/images/bg_grey.gif +0 -0
- data/site/images/bullet.jpg +0 -0
- data/site/images/corner_green.gif +0 -0
- data/site/images/corner_green.psd +0 -0
- data/site/images/corner_pink.gif +0 -0
- data/site/images/god_logo1.gif +0 -0
- data/site/images/header_bg.gif +0 -0
- data/site/images/header_bg.jpg +0 -0
- data/site/images/red_dot.gif +0 -0
- data/site/images/top_bg.gif +0 -0
- data/site/index.html +563 -0
- data/site/install.html +2 -0
- data/site/javascripts/code_highlighter.js +188 -0
- data/site/javascripts/ruby.js +18 -0
- data/site/stylesheets/layout.css +174 -0
- data/test/configs/lifecycle/lifecycle.god +25 -0
- data/test/test_god.rb +2 -2
- data/test/test_jabber.rb +36 -0
- data/test/test_logger.rb +4 -1
- metadata +56 -22
- data/Manifest.txt +0 -114
data/site/install.html
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
/* Unobtrustive Code Highlighter By Dan Webb 11/2005
|
2
|
+
Version: 0.4
|
3
|
+
|
4
|
+
Usage:
|
5
|
+
Add a script tag for this script and any stylesets you need to use
|
6
|
+
to the page in question, add correct class names to CODE elements,
|
7
|
+
define CSS styles for elements. That's it!
|
8
|
+
|
9
|
+
Known to work on:
|
10
|
+
IE 5.5+ PC
|
11
|
+
Firefox/Mozilla PC/Mac
|
12
|
+
Opera 7.23 + PC
|
13
|
+
Safari 2
|
14
|
+
|
15
|
+
Known to degrade gracefully on:
|
16
|
+
IE5.0 PC
|
17
|
+
|
18
|
+
Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors
|
19
|
+
in older browsers use expressions that use lookahead in string format when defining stylesets.
|
20
|
+
|
21
|
+
This script is inspired by star-light by entirely cunning Dean Edwards
|
22
|
+
http://dean.edwards.name/star-light/.
|
23
|
+
*/
|
24
|
+
|
25
|
+
// replace callback support for safari.
|
26
|
+
if ("a".replace(/a/, function() {return "b"}) != "b") (function(){
|
27
|
+
var default_replace = String.prototype.replace;
|
28
|
+
String.prototype.replace = function(search,replace){
|
29
|
+
// replace is not function
|
30
|
+
if(typeof replace != "function"){
|
31
|
+
return default_replace.apply(this,arguments)
|
32
|
+
}
|
33
|
+
var str = "" + this;
|
34
|
+
var callback = replace;
|
35
|
+
// search string is not RegExp
|
36
|
+
if(!(search instanceof RegExp)){
|
37
|
+
var idx = str.indexOf(search);
|
38
|
+
return (
|
39
|
+
idx == -1 ? str :
|
40
|
+
default_replace.apply(str,[search,callback(search, idx, str)])
|
41
|
+
)
|
42
|
+
}
|
43
|
+
var reg = search;
|
44
|
+
var result = [];
|
45
|
+
var lastidx = reg.lastIndex;
|
46
|
+
var re;
|
47
|
+
while((re = reg.exec(str)) != null){
|
48
|
+
var idx = re.index;
|
49
|
+
var args = re.concat(idx, str);
|
50
|
+
result.push(
|
51
|
+
str.slice(lastidx,idx),
|
52
|
+
callback.apply(null,args).toString()
|
53
|
+
);
|
54
|
+
if(!reg.global){
|
55
|
+
lastidx += RegExp.lastMatch.length;
|
56
|
+
break
|
57
|
+
}else{
|
58
|
+
lastidx = reg.lastIndex;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
result.push(str.slice(lastidx));
|
62
|
+
return result.join("")
|
63
|
+
}
|
64
|
+
})();
|
65
|
+
|
66
|
+
var CodeHighlighter = { styleSets : new Array };
|
67
|
+
|
68
|
+
CodeHighlighter.addStyle = function(name, rules) {
|
69
|
+
// using push test to disallow older browsers from adding styleSets
|
70
|
+
if ([].push) this.styleSets.push({
|
71
|
+
name : name,
|
72
|
+
rules : rules,
|
73
|
+
ignoreCase : arguments[2] || false
|
74
|
+
})
|
75
|
+
|
76
|
+
function setEvent() {
|
77
|
+
// set highlighter to run on load (use LowPro if present)
|
78
|
+
if (typeof Event != 'undefined' && typeof Event.onReady == 'function')
|
79
|
+
return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter));
|
80
|
+
|
81
|
+
var old = window.onload;
|
82
|
+
|
83
|
+
if (typeof window.onload != 'function') {
|
84
|
+
window.onload = function() { CodeHighlighter.init() };
|
85
|
+
} else {
|
86
|
+
window.onload = function() {
|
87
|
+
old();
|
88
|
+
CodeHighlighter.init();
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
// only set the event when the first style is added
|
94
|
+
if (this.styleSets.length==1) setEvent();
|
95
|
+
}
|
96
|
+
|
97
|
+
CodeHighlighter.init = function() {
|
98
|
+
if (!document.getElementsByTagName) return;
|
99
|
+
if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function
|
100
|
+
// throw out older browsers
|
101
|
+
|
102
|
+
var codeEls = document.getElementsByTagName("CODE");
|
103
|
+
// collect array of all pre elements
|
104
|
+
codeEls.filter = function(f) {
|
105
|
+
var a = new Array;
|
106
|
+
for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i];
|
107
|
+
return a;
|
108
|
+
}
|
109
|
+
|
110
|
+
var rules = new Array;
|
111
|
+
rules.toString = function() {
|
112
|
+
// joins regexes into one big parallel regex
|
113
|
+
var exps = new Array;
|
114
|
+
for (var i = 0; i < this.length; i++) exps.push(this[i].exp);
|
115
|
+
return exps.join("|");
|
116
|
+
}
|
117
|
+
|
118
|
+
function addRule(className, rule) {
|
119
|
+
// add a replace rule
|
120
|
+
var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp;
|
121
|
+
// converts regex rules to strings and chops of the slashes
|
122
|
+
rules.push({
|
123
|
+
className : className,
|
124
|
+
exp : "(" + exp + ")",
|
125
|
+
length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule
|
126
|
+
replacement : rule.replacement || null
|
127
|
+
});
|
128
|
+
}
|
129
|
+
|
130
|
+
function parse(text, ignoreCase) {
|
131
|
+
// main text parsing and replacement
|
132
|
+
return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() {
|
133
|
+
var i = 0, j = 1, rule;
|
134
|
+
while (rule = rules[i++]) {
|
135
|
+
if (arguments[j]) {
|
136
|
+
// if no custom replacement defined do the simple replacement
|
137
|
+
if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>";
|
138
|
+
else {
|
139
|
+
// replace $0 with the className then do normal replaces
|
140
|
+
var str = rule.replacement.replace("$0", rule.className);
|
141
|
+
for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]);
|
142
|
+
return str;
|
143
|
+
}
|
144
|
+
} else j+= rule.length;
|
145
|
+
}
|
146
|
+
});
|
147
|
+
}
|
148
|
+
|
149
|
+
function highlightCode(styleSet) {
|
150
|
+
// clear rules array
|
151
|
+
var parsed, clsRx = new RegExp("(\\s|^)" + styleSet.name + "(\\s|$)");
|
152
|
+
rules.length = 0;
|
153
|
+
|
154
|
+
// get stylable elements by filtering out all code elements without the correct className
|
155
|
+
var stylableEls = codeEls.filter(function(item) { return clsRx.test(item.className) });
|
156
|
+
|
157
|
+
// add style rules to parser
|
158
|
+
for (var className in styleSet.rules) addRule(className, styleSet.rules[className]);
|
159
|
+
|
160
|
+
|
161
|
+
// replace for all elements
|
162
|
+
for (var i = 0; i < stylableEls.length; i++) {
|
163
|
+
// EVIL hack to fix IE whitespace badness if it's inside a <pre>
|
164
|
+
if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
|
165
|
+
stylableEls[i] = stylableEls[i].parentNode;
|
166
|
+
|
167
|
+
parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() {
|
168
|
+
return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>"
|
169
|
+
});
|
170
|
+
parsed = parsed.replace(/\n( *)/g, function() {
|
171
|
+
var spaces = "";
|
172
|
+
for (var i = 0; i < arguments[1].length; i++) spaces+= " ";
|
173
|
+
return "\n" + spaces;
|
174
|
+
});
|
175
|
+
parsed = parsed.replace(/\t/g, " ");
|
176
|
+
parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>");
|
177
|
+
|
178
|
+
} else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase);
|
179
|
+
|
180
|
+
stylableEls[i].innerHTML = parsed;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
// run highlighter on all stylesets
|
185
|
+
for (var i=0; i < this.styleSets.length; i++) {
|
186
|
+
highlightCode(this.styleSets[i]);
|
187
|
+
}
|
188
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
CodeHighlighter.addStyle("ruby",{
|
2
|
+
comment : {
|
3
|
+
exp : /#[^\n]+/
|
4
|
+
},
|
5
|
+
brackets : {
|
6
|
+
exp : /\(|\)/
|
7
|
+
},
|
8
|
+
string : {
|
9
|
+
exp : /'[^']*'|"[^"]*"/
|
10
|
+
},
|
11
|
+
keywords : {
|
12
|
+
exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|require|raise)\b/
|
13
|
+
},
|
14
|
+
/* Added by Shelly Fisher (shelly@agileevolved.com) */
|
15
|
+
symbol : {
|
16
|
+
exp : /([^:])(:[A-Za-z0-9_!?]+)/
|
17
|
+
}
|
18
|
+
});
|
@@ -0,0 +1,174 @@
|
|
1
|
+
* {
|
2
|
+
margin: 0;
|
3
|
+
font-size: 100%;
|
4
|
+
}
|
5
|
+
|
6
|
+
body {
|
7
|
+
font: normal .8em/1.5em "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
|
8
|
+
color: #484848;
|
9
|
+
background: #E6EAE9 url(../images/bg_grey.gif);
|
10
|
+
}
|
11
|
+
|
12
|
+
a {
|
13
|
+
color: #c75f3e;
|
14
|
+
text-decoration: none;
|
15
|
+
}
|
16
|
+
|
17
|
+
a:hover,
|
18
|
+
a:active {
|
19
|
+
text-decoration: underline;
|
20
|
+
}
|
21
|
+
|
22
|
+
#mothership {
|
23
|
+
width: 307px;
|
24
|
+
height: 117px;
|
25
|
+
margin: 0 auto;
|
26
|
+
background: url(../images/god_logo1.gif);
|
27
|
+
}
|
28
|
+
|
29
|
+
#content {
|
30
|
+
width: 700px;
|
31
|
+
margin: 3px auto;
|
32
|
+
background: white;
|
33
|
+
border: 1px solid #444;
|
34
|
+
padding: 0 24px;
|
35
|
+
background: #f8f8ff;
|
36
|
+
overflow: hidden;
|
37
|
+
}
|
38
|
+
|
39
|
+
.banner {
|
40
|
+
margin-top: 24px;
|
41
|
+
border: 1px solid #ddd;
|
42
|
+
width: 698px;
|
43
|
+
height: 150px;
|
44
|
+
background: url(../images/banner.jpg);
|
45
|
+
}
|
46
|
+
|
47
|
+
#menu {
|
48
|
+
margin-top: 5px;
|
49
|
+
}
|
50
|
+
|
51
|
+
#menu div.dots {
|
52
|
+
background: url(../images/red_dot.gif) repeat;
|
53
|
+
height: 5px;
|
54
|
+
width: 700px;
|
55
|
+
font-size: 0;
|
56
|
+
}
|
57
|
+
|
58
|
+
#menu ul {
|
59
|
+
font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
|
60
|
+
font-weight: bold;
|
61
|
+
text-transform: uppercase;
|
62
|
+
color: #4D4D4D;
|
63
|
+
font-size: 12px;
|
64
|
+
padding: 0;
|
65
|
+
margin: 0;
|
66
|
+
margin-top: 0 !important;
|
67
|
+
margin-top: -2px;
|
68
|
+
}
|
69
|
+
|
70
|
+
#menu li {
|
71
|
+
display: inline;
|
72
|
+
margin: 0 30px 0 0;
|
73
|
+
}
|
74
|
+
|
75
|
+
#menu a:link,
|
76
|
+
#menu a:visited {
|
77
|
+
color: #4D4D4D;
|
78
|
+
text-decoration: none;
|
79
|
+
}
|
80
|
+
|
81
|
+
#menu a:hover,
|
82
|
+
#menu a:active {
|
83
|
+
color: black;
|
84
|
+
text-decoration: none;
|
85
|
+
}
|
86
|
+
|
87
|
+
#page_home #menu li.menu_home a {
|
88
|
+
color: #A70000;
|
89
|
+
}
|
90
|
+
|
91
|
+
.columnleft {
|
92
|
+
float: left;
|
93
|
+
width: 325px;
|
94
|
+
margin-bottom: 20px;
|
95
|
+
}
|
96
|
+
|
97
|
+
.columnleft p {
|
98
|
+
text-align: justify;
|
99
|
+
}
|
100
|
+
|
101
|
+
.columnright {
|
102
|
+
float: right;
|
103
|
+
width: 325px;
|
104
|
+
margin-bottom: 20px;
|
105
|
+
}
|
106
|
+
|
107
|
+
h1 {
|
108
|
+
font: bold 1.5em "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
|
109
|
+
color: #f36e21;
|
110
|
+
text-transform: uppercase;
|
111
|
+
margin: 1.5em 0 .5em 0;
|
112
|
+
clear: both;
|
113
|
+
}
|
114
|
+
|
115
|
+
p {
|
116
|
+
margin-bottom: 1em;
|
117
|
+
}
|
118
|
+
|
119
|
+
ul {
|
120
|
+
margin-bottom: 1em;
|
121
|
+
}
|
122
|
+
|
123
|
+
ul.features {
|
124
|
+
padding: 0;
|
125
|
+
margin-left: 1.5em !important;
|
126
|
+
margin-left: 1.3em;
|
127
|
+
}
|
128
|
+
|
129
|
+
ul.features li {
|
130
|
+
list-style-position: outside;
|
131
|
+
list-style-type: circle;
|
132
|
+
list-style-image: url(../images/bullet.jpg);
|
133
|
+
line-height: 1.4em;
|
134
|
+
}
|
135
|
+
|
136
|
+
#footer {
|
137
|
+
text-align: center;
|
138
|
+
color: white;
|
139
|
+
margin-bottom: 50px;
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
pre {
|
145
|
+
line-height: 1.3;
|
146
|
+
border: 1px solid #ccc;
|
147
|
+
padding: 1em;
|
148
|
+
background-color: #efefef;
|
149
|
+
margin: 1em 0;
|
150
|
+
}
|
151
|
+
|
152
|
+
code {
|
153
|
+
font-size: 1.2em;
|
154
|
+
}
|
155
|
+
|
156
|
+
.ruby .keywords {
|
157
|
+
color: blue;
|
158
|
+
}
|
159
|
+
|
160
|
+
.ruby .comment {
|
161
|
+
color : green;
|
162
|
+
}
|
163
|
+
|
164
|
+
.ruby .string {
|
165
|
+
color : teal;
|
166
|
+
}
|
167
|
+
|
168
|
+
.ruby .keywords {
|
169
|
+
color : navy;
|
170
|
+
}
|
171
|
+
|
172
|
+
.ruby .brackets {
|
173
|
+
color : navy;
|
174
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
God::Contacts::Twitter.settings = {
|
2
|
+
# this is for my 'mojombo2' twitter test account
|
3
|
+
# feel free to use it for testing your conditions
|
4
|
+
:username => 'mojombo@gmail.com',
|
5
|
+
:password => 'gok9we3ot1av2e'
|
6
|
+
}
|
7
|
+
|
8
|
+
God.contact(:twitter) do |c|
|
9
|
+
c.name = 'tom2'
|
10
|
+
c.group = 'developers'
|
11
|
+
end
|
12
|
+
|
13
|
+
God.watch do |w|
|
14
|
+
w.name = "lifecycle"
|
15
|
+
w.interval = 5.seconds
|
16
|
+
w.start = "/dev/null"
|
17
|
+
|
18
|
+
# lifecycle
|
19
|
+
w.lifecycle do |on|
|
20
|
+
on.condition(:always) do |c|
|
21
|
+
c.what = true
|
22
|
+
c.notify = "tom2"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/test/test_god.rb
CHANGED
@@ -542,11 +542,11 @@ class TestGod < Test::Unit::TestCase
|
|
542
542
|
# pattern_match
|
543
543
|
|
544
544
|
def test_pattern_match
|
545
|
-
list = %w{ mongrel-3000 mongrel-3001 fuzed fuzed2 apache mysql}
|
545
|
+
list = %w{ mongrel-3000 mongrel-3001 fuzed22 fuzed fuzed2 apache mysql}
|
546
546
|
|
547
547
|
assert_equal %w{ mongrel-3000 }, God.pattern_match('m3000', list)
|
548
548
|
assert_equal %w{ mongrel-3001 }, God.pattern_match('m31', list)
|
549
|
-
assert_equal %w{ fuzed fuzed2 }, God.pattern_match('fu', list)
|
549
|
+
assert_equal %w{ fuzed fuzed2 fuzed22}, God.pattern_match('fu', list)
|
550
550
|
assert_equal %w{ mysql }, God.pattern_match('sql', list)
|
551
551
|
end
|
552
552
|
end
|
data/test/test_jabber.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/helper'
|
3
|
+
|
4
|
+
class TestJabber < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
God::Contacts::Jabber.settings = {
|
8
|
+
:jabber_id => 'test@example.com',
|
9
|
+
:password => 'pass'
|
10
|
+
}
|
11
|
+
@jabber = God::Contacts::Jabber.new
|
12
|
+
@jabber.jabber_id = 'recipient@example.com'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_notify
|
16
|
+
assert_nothing_raised do
|
17
|
+
God::Contacts::Jabber.any_instance.expects(:connect!).once.returns(nil)
|
18
|
+
God::Contacts::Jabber.any_instance.expects(:send!).once.returns(nil)
|
19
|
+
@jabber.notify(:a, :b, :c, :d, :e)
|
20
|
+
assert_equal "sent jabber message to recipient@example.com", @jabber.info
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# def test_live_notify
|
25
|
+
# God::Contacts::Jabber.settings = {
|
26
|
+
# :jabber_id => 'real_user@example.com',
|
27
|
+
# :password => 'pass'
|
28
|
+
# }
|
29
|
+
# recipient = "real_recipient@example.com"
|
30
|
+
#
|
31
|
+
# jabber = God::Contacts::Jabber.new
|
32
|
+
# jabber.jabber_id = recipient
|
33
|
+
# jabber.notify("Hello", Time.now, "Test", "Test", "localhost")
|
34
|
+
# assert_equal "sent jabber message to #{recipient}", jabber.info
|
35
|
+
# end
|
36
|
+
end
|