sqrbl 0.1.0
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 +4 -0
- data/LICENSE.txt +621 -0
- data/README.txt +85 -0
- data/Rakefile +32 -0
- data/TODO.txt +11 -0
- data/bin/sqrbl +8 -0
- data/lib/core_exts/object.rb +44 -0
- data/lib/core_exts/symbol.rb +16 -0
- data/lib/sqrbl/base_migration_writer.rb +52 -0
- data/lib/sqrbl/call_stack.rb +21 -0
- data/lib/sqrbl/group.rb +42 -0
- data/lib/sqrbl/individual_migration_writer.rb +48 -0
- data/lib/sqrbl/migration.rb +62 -0
- data/lib/sqrbl/mixins/expects_block_with_new.rb +27 -0
- data/lib/sqrbl/mixins/has_todos.rb +65 -0
- data/lib/sqrbl/mixins/method_missing_delegation.rb +83 -0
- data/lib/sqrbl/step.rb +192 -0
- data/lib/sqrbl/step_pair.rb +56 -0
- data/lib/sqrbl/unified_migration_writer.rb +34 -0
- data/lib/sqrbl.rb +83 -0
- data/spec/README.txt +4 -0
- data/spec/functional/base_migration_writer_spec.rb +12 -0
- data/spec/functional/individual_migration_writer_spec.rb +172 -0
- data/spec/functional/unified_migration_writer_spec.rb +97 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/unit/group_spec.rb +85 -0
- data/spec/unit/migration_spec.rb +68 -0
- data/spec/unit/sqrbl_spec.rb +28 -0
- data/spec/unit/step_pair_spec.rb +110 -0
- data/spec/unit/step_spec.rb +154 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- metadata +115 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
|
3
|
+
include Sqrbl
|
4
|
+
|
5
|
+
describe Group do
|
6
|
+
before(:each) do
|
7
|
+
@mig = mock('Migration')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should evaluate the block in its own context" do
|
11
|
+
group = Group.new(@mig, "foo", :skip_block_evaluation => true) do
|
12
|
+
hello_world()
|
13
|
+
end
|
14
|
+
group.should_receive(:hello_world)
|
15
|
+
group.send(:evaluate_block!)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should delegate method_missing calls back to the migration object" do
|
19
|
+
@mig.should_receive(:goodbye_world)
|
20
|
+
group = Group.new(@mig, "foo") do
|
21
|
+
goodbye_world()
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "methods defined in the group block should become available as methods on the Group instance" do
|
26
|
+
group = Group.new(@mig, "foo") do
|
27
|
+
def hello_world
|
28
|
+
"Hello, world!"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
group.should respond_to(:hello_world)
|
32
|
+
group.hello_world.should == "Hello, world!"
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "when #todo is called" do
|
36
|
+
it "should create a Todo object that saves the message" do
|
37
|
+
group = Group.new(@mig, 'foo') { todo 'bar' }
|
38
|
+
group.todos.map(&:message).should == ['bar']
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should create a Todo object that saves the location of the #todo call" do
|
42
|
+
group = Group.new(@mig, 'foo') { todo 'bar' }; line_num = __LINE__
|
43
|
+
group.todos.first.location.should == [__FILE__, line_num].join(':')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "when #step is called" do
|
48
|
+
it "should create a StepPair object and pass it the group, the description, and the block arg" do
|
49
|
+
test_self = self
|
50
|
+
group = Group.new(@mig, "foo") do
|
51
|
+
StepPair.should_receive(:new).with(self, 'do something').and_yield # Look weird? See ./README.txt
|
52
|
+
step('do something') {}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe :valid? do
|
58
|
+
it "should return false if steps is empty" do
|
59
|
+
group = Group.new(@mig, "foo") {}
|
60
|
+
group.should_not be_valid
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return false if steps is not empty, but any step is invalid" do
|
64
|
+
group = Group.new(@mig, "foo") { step("foo") {} }
|
65
|
+
group.steps.map(&:valid?).should include(false)
|
66
|
+
group.should_not be_valid
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return true if steps is not empty, and all steps are themselves valid" do
|
70
|
+
group = Group.new(@mig, "foo") do
|
71
|
+
step("foo") do
|
72
|
+
up {}
|
73
|
+
down {}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
group.should be_valid
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should have a unix_name property that consists of the regular name with characters sanitized" do
|
81
|
+
group = Group.new(@mig, "This be a test, matey! ARRR!!") {}
|
82
|
+
group.unix_name.should == 'this_be_a_test_matey_arrr'
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
|
3
|
+
include Sqrbl
|
4
|
+
|
5
|
+
describe Migration do
|
6
|
+
describe "A new migration" do
|
7
|
+
it "should know the file that created it" do
|
8
|
+
mig = Migration.new
|
9
|
+
mig.creating_file.should == File.expand_path(__FILE__)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "A migration built with Migration.build" do
|
14
|
+
it "should still know the file that created it" do
|
15
|
+
mig = Migration.build {}
|
16
|
+
mig.creating_file.should == File.expand_path(__FILE__)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "when the block calls #group once" do
|
20
|
+
it "should have one group with the proper description" do
|
21
|
+
mig = Migration.build do
|
22
|
+
group "first group" do
|
23
|
+
'hello world'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
mig.groups.all? { |group| group.should be_kind_of(Group) }
|
27
|
+
mig.groups.map(&:description).should == ['first group']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "when the block calls #group twice" do
|
32
|
+
it "should have two group with the proper descriptions" do
|
33
|
+
mig = Migration.build do
|
34
|
+
group "first group" do
|
35
|
+
'hello world'
|
36
|
+
end
|
37
|
+
group "second group" do
|
38
|
+
'goodbye world'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
mig.groups.all? { |group| group.should be_kind_of(Group) }
|
42
|
+
mig.groups.map(&:description).should == ['first group', 'second group']
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should pass itself as a dependency to any group it builds" do
|
47
|
+
mig = Migration.build do
|
48
|
+
group("first group" ) { '' }
|
49
|
+
group("second group" ) { '' }
|
50
|
+
group("group the third") { '' }
|
51
|
+
end
|
52
|
+
|
53
|
+
mig.groups.all? { |group| group.migration.should == mig }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "when #todo is called" do
|
58
|
+
it "should create a Todo object that saves the message" do
|
59
|
+
mig = Migration.build { todo 'foo' }
|
60
|
+
mig.todos.map(&:message).should == ['foo']
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should create a Todo object that saves the location of the #todo call" do
|
64
|
+
mig = Migration.build { todo 'foo' }; line_num = __LINE__
|
65
|
+
mig.todos.first.location.should == [__FILE__, line_num].join(':')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
|
3
|
+
include Sqrbl
|
4
|
+
|
5
|
+
describe Sqrbl do
|
6
|
+
it ".build_migration should return an instance of Sqrbl::Migration" do
|
7
|
+
migration = Sqrbl.build_migration { 'hello, world!' }
|
8
|
+
migration.should be_kind_of(Sqrbl::Migration)
|
9
|
+
end
|
10
|
+
|
11
|
+
it ".migration should take the return value from Sqrbl::Migration.build and pass it to write_migration" do
|
12
|
+
mig = mock('Migration')
|
13
|
+
Migration.should_receive(:build).and_yield.and_return(mig)
|
14
|
+
Sqrbl.should_receive(:write_migration!).with(mig)
|
15
|
+
Sqrbl.migration { 'Hello, world!' }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe :write_migration! do
|
19
|
+
it "should take a migration object and pass it off to any and all writers that exist" do
|
20
|
+
mig = mock('Migration')
|
21
|
+
BaseMigrationWriter.subclasses.each do |writer_class|
|
22
|
+
writer_class.should_receive(:write_migration!).with(mig)
|
23
|
+
end
|
24
|
+
Sqrbl.write_migration!(mig)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
|
3
|
+
include Sqrbl
|
4
|
+
|
5
|
+
describe StepPair do
|
6
|
+
before(:each) do
|
7
|
+
@group = mock('Group')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should evaluate the block in its own context" do
|
11
|
+
step_pair = StepPair.new(@group, "foo", :skip_block_evaluation => true) do
|
12
|
+
hello_world()
|
13
|
+
end
|
14
|
+
step_pair.should_receive(:hello_world)
|
15
|
+
step_pair.send(:evaluate_block!)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should delegate method_missing calls back to the group object" do
|
19
|
+
@group.should_receive(:goodbye_world)
|
20
|
+
step_pair = StepPair.new(@group, "foo") do
|
21
|
+
goodbye_world()
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "methods defined in the step_pair block should become available as methods on the StepPair instance" do
|
26
|
+
step_pair = StepPair.new(@group, "foo") do
|
27
|
+
def hello_world
|
28
|
+
"Hello, world!"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
step_pair.should respond_to(:hello_world)
|
32
|
+
step_pair.hello_world.should == "Hello, world!"
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "when #up is called" do
|
36
|
+
it "should create a Step object and pass it the StepPair and the block arg" do
|
37
|
+
step_pair = StepPair.new(@group, "foo") do
|
38
|
+
Step.should_receive(:new).with(self).and_yield # Look weird? See ./README.txt
|
39
|
+
up {}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should put the Step object in its up_step attribute" do
|
44
|
+
step_pair = StepPair.new(@group, "foo") do
|
45
|
+
up {}
|
46
|
+
end
|
47
|
+
step_pair.up_step.should be_kind_of(Step)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "when #down is called" do
|
52
|
+
it "should create a Step object and pass it the StepPair and the block arg" do
|
53
|
+
step_pair = StepPair.new(@group, "foo") do
|
54
|
+
Step.should_receive(:new).with(self).and_yield # Look weird? See ./README.txt
|
55
|
+
down {}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should put the Step object in its down_step attribute" do
|
60
|
+
step_pair = StepPair.new(@group, "foo") do
|
61
|
+
down {}
|
62
|
+
end
|
63
|
+
step_pair.down_step.should be_kind_of(Step)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe :valid? do
|
68
|
+
it "should return false if up_step is nil" do
|
69
|
+
step_pair = StepPair.new(@group, "foo") do
|
70
|
+
end
|
71
|
+
step_pair.should_not be_valid
|
72
|
+
end
|
73
|
+
it "should return false if up_step is nil and down_step is not nil" do
|
74
|
+
step_pair = StepPair.new(@group, "foo") do
|
75
|
+
down {}
|
76
|
+
end
|
77
|
+
step_pair.should_not be_valid
|
78
|
+
end
|
79
|
+
it "should return false if up_step is not nil and down_step is nil" do
|
80
|
+
step_pair = StepPair.new(@group, "foo") do
|
81
|
+
up {}
|
82
|
+
end
|
83
|
+
step_pair.should_not be_valid
|
84
|
+
end
|
85
|
+
it "should return true if neither up_step and down_step is nil" do
|
86
|
+
step_pair = StepPair.new(@group, "foo") do
|
87
|
+
up {}
|
88
|
+
down {}
|
89
|
+
end
|
90
|
+
step_pair.should be_valid
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "when #todo is called" do
|
95
|
+
it "should create a Todo object that saves the message" do
|
96
|
+
pair = StepPair.new(@group, 'foo') { todo 'bar' }
|
97
|
+
pair.todos.map(&:message).should == ['bar']
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should create a Todo object that saves the location of the #todo call" do
|
101
|
+
pair = StepPair.new(@group, 'foo') { todo 'bar' }; line_num = __LINE__
|
102
|
+
pair.todos.first.location.should == [__FILE__, line_num].join(':')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should have a unix_name property that consists of the regular name with characters sanitized" do
|
107
|
+
pair = StepPair.new(@group, "This be a test, matey! ARRR!!") {}
|
108
|
+
pair.unix_name.should == 'this_be_a_test_matey_arrr'
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
|
3
|
+
include Sqrbl
|
4
|
+
|
5
|
+
describe Step do
|
6
|
+
before(:each) do
|
7
|
+
@pair = mock('StepPair')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should evaluate the block in its own context" do
|
11
|
+
step = Step.new(@pair, :skip_block_evaluation => true) do
|
12
|
+
hello_world()
|
13
|
+
end
|
14
|
+
step.should_receive(:hello_world)
|
15
|
+
step.send(:evaluate_block!)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should delegate method_missing calls back to the step_pair object" do
|
19
|
+
@pair.should_receive(:goodbye_world)
|
20
|
+
step = Step.new(@pair) do
|
21
|
+
goodbye_world()
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "methods defined in the step's block should become available as methods on the Step instance" do
|
26
|
+
step = Step.new(@pair) do
|
27
|
+
def hello_world
|
28
|
+
"Hello, world!"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
step.should respond_to(:hello_world)
|
32
|
+
step.hello_world.should == "Hello, world!"
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "when #todo is called" do
|
36
|
+
it "should create a Todo object that saves the message" do
|
37
|
+
step = Step.new(@pair) { todo 'foo' }
|
38
|
+
step.todos.map(&:message).should == ['foo']
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should create a Todo object that saves the location of the #todo call" do
|
42
|
+
step = Step.new(@pair) { todo 'foo' }; line_num = __LINE__
|
43
|
+
step.todos.first.location.should == [__FILE__, line_num].join(':')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should prepend its argument with '--> todo ([file], line [line #]):' and put it in #output" do
|
47
|
+
line_num = 0
|
48
|
+
step = Step.new(@pair) do
|
49
|
+
todo 'Fix a terrible issue'; line_num = __LINE__
|
50
|
+
end
|
51
|
+
|
52
|
+
step.output.should =~ /^--> todo \(.*\)\:/i
|
53
|
+
step.output.should include(__FILE__)
|
54
|
+
step.output.should =~ Regexp.new("line #{line_num}")
|
55
|
+
step.output.should include('Fix a terrible issue')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "when #comment is called" do
|
60
|
+
it "should prepend its argument with '-- ' and put it in #output" do
|
61
|
+
message = "Here's something you should probably be aware of."
|
62
|
+
step = Step.new(@pair) { comment(message) }
|
63
|
+
step.output.should =~ Regexp.new('^-- ' + message)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "when #block_comment is called" do
|
68
|
+
it "should surround its argument with /* and */ on newlines and put the whole thing in #output" do
|
69
|
+
message = "Here's something you should probably be aware of."
|
70
|
+
step = Step.new(@pair) { block_comment { message } }
|
71
|
+
step.output.should =~ /^\/\*/
|
72
|
+
step.output.should =~ Regexp.new('^ ' + message)
|
73
|
+
step.output.should =~ /^\*\//
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "and given a string with extra spaces (as, e.g., a heredoc)" do
|
77
|
+
it "should unindent the argument before putting it in #output" do
|
78
|
+
step = Step.new(@pair) do
|
79
|
+
block_comment do
|
80
|
+
<<-EOF
|
81
|
+
Foo.
|
82
|
+
Bar.
|
83
|
+
Baz.
|
84
|
+
EOF
|
85
|
+
end
|
86
|
+
end
|
87
|
+
step.output.should =~ /^ Foo./
|
88
|
+
step.output.should =~ /^ Bar./
|
89
|
+
step.output.should =~ /^ Baz./
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "when #warning is called" do
|
95
|
+
it "should create a Todo object with type=:warning that saves the message" do
|
96
|
+
step = Step.new(@pair) { warning 'Danger, Will Robinson!' }
|
97
|
+
step.todos.map(&:type).should == [:warning]
|
98
|
+
step.todos.map(&:message).should == ['Danger, Will Robinson!']
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should write a giant ASCII warning to #output" do
|
102
|
+
line_num = 0
|
103
|
+
step = Step.new(@pair) do
|
104
|
+
warning 'Danger, Will Robinson!'; line_num = __LINE__
|
105
|
+
end
|
106
|
+
step.output.should include(Step::GiantWarningSeparator)
|
107
|
+
step.output.should include(Step::GiantWarningText)
|
108
|
+
step.output.should include('Danger, Will Robinson!')
|
109
|
+
step.output.should =~ Regexp.new("line #{line_num}")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "when #action is called with a string and a block" do
|
114
|
+
before(:each) do
|
115
|
+
@step = Step.new(@pair) do
|
116
|
+
action "Do something" do
|
117
|
+
<<-EOF
|
118
|
+
Hello world!
|
119
|
+
EOF
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should treat the string as a comment" do
|
125
|
+
@step.output.should =~ /^-- Do something/
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should unindent the return value from the block and put it in #output" do
|
129
|
+
@step.output.should =~ /^Hello world!/
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#insert_into" do
|
134
|
+
it "should produce an INSERT INTO fragment" do
|
135
|
+
@step = Step.new(@pair) {}
|
136
|
+
insert_fragment = @step.insert_into 'new_widgets', {
|
137
|
+
:name => 'widget_name',
|
138
|
+
:part_num => 'CONCAT("X_", part_number)',
|
139
|
+
:note => '"Imported from old_widgets"',
|
140
|
+
}
|
141
|
+
# puts '<pre>%s</pre>' % insert_fragment
|
142
|
+
|
143
|
+
insert_fragment.should include('new_widgets')
|
144
|
+
|
145
|
+
insert_fragment.should =~ /^\s*name/
|
146
|
+
insert_fragment.should =~ /^\s*part_num/
|
147
|
+
insert_fragment.should =~ /^\s*note/
|
148
|
+
|
149
|
+
insert_fragment.should include('widget_name AS name')
|
150
|
+
insert_fragment.should include('CONCAT("X_", part_number) AS part_num')
|
151
|
+
insert_fragment.should include('"Imported from old_widgets" AS note')
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/tasks/ann.rake
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'bones/smtp_tls'
|
4
|
+
rescue LoadError
|
5
|
+
require 'net/smtp'
|
6
|
+
end
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
namespace :ann do
|
10
|
+
|
11
|
+
# A prerequisites task that all other tasks depend upon
|
12
|
+
task :prereqs
|
13
|
+
|
14
|
+
file PROJ.ann.file do
|
15
|
+
ann = PROJ.ann
|
16
|
+
puts "Generating #{ann.file}"
|
17
|
+
File.open(ann.file,'w') do |fd|
|
18
|
+
fd.puts("#{PROJ.name} version #{PROJ.version}")
|
19
|
+
fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
|
20
|
+
fd.puts(" #{PROJ.url}") if PROJ.url.valid?
|
21
|
+
fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
|
22
|
+
fd.puts
|
23
|
+
fd.puts("== DESCRIPTION")
|
24
|
+
fd.puts
|
25
|
+
fd.puts(PROJ.description)
|
26
|
+
fd.puts
|
27
|
+
fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
|
28
|
+
fd.puts
|
29
|
+
ann.paragraphs.each do |p|
|
30
|
+
fd.puts "== #{p.upcase}"
|
31
|
+
fd.puts
|
32
|
+
fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
|
33
|
+
fd.puts
|
34
|
+
end
|
35
|
+
fd.puts ann.text if ann.text
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Create an announcement file"
|
40
|
+
task :announcement => ['ann:prereqs', PROJ.ann.file]
|
41
|
+
|
42
|
+
desc "Send an email announcement"
|
43
|
+
task :email => ['ann:prereqs', PROJ.ann.file] do
|
44
|
+
ann = PROJ.ann
|
45
|
+
from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
|
46
|
+
to = Array(ann.email[:to])
|
47
|
+
|
48
|
+
### build a mail header for RFC 822
|
49
|
+
rfc822msg = "From: #{from}\n"
|
50
|
+
rfc822msg << "To: #{to.join(',')}\n"
|
51
|
+
rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
|
52
|
+
rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
|
53
|
+
rfc822msg << "\n"
|
54
|
+
rfc822msg << "Date: #{Time.new.rfc822}\n"
|
55
|
+
rfc822msg << "Message-Id: "
|
56
|
+
rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
|
57
|
+
rfc822msg << File.read(ann.file)
|
58
|
+
|
59
|
+
params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
|
60
|
+
ann.email[key]
|
61
|
+
end
|
62
|
+
|
63
|
+
params[3] = PROJ.email if params[3].nil?
|
64
|
+
|
65
|
+
if params[4].nil?
|
66
|
+
STDOUT.write "Please enter your e-mail password (#{params[3]}): "
|
67
|
+
params[4] = STDIN.gets.chomp
|
68
|
+
end
|
69
|
+
|
70
|
+
### send email
|
71
|
+
Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
|
72
|
+
end
|
73
|
+
end # namespace :ann
|
74
|
+
|
75
|
+
desc 'Alias to ann:announcement'
|
76
|
+
task :ann => 'ann:announcement'
|
77
|
+
|
78
|
+
CLOBBER << PROJ.ann.file
|
79
|
+
|
80
|
+
# EOF
|
data/tasks/bones.rake
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
if HAVE_BONES
|
3
|
+
|
4
|
+
namespace :bones do
|
5
|
+
|
6
|
+
desc 'Show the PROJ open struct'
|
7
|
+
task :debug do |t|
|
8
|
+
atr = if t.application.top_level_tasks.length == 2
|
9
|
+
t.application.top_level_tasks.pop
|
10
|
+
end
|
11
|
+
|
12
|
+
if atr then Bones::Debug.show_attr(PROJ, atr)
|
13
|
+
else Bones::Debug.show PROJ end
|
14
|
+
end
|
15
|
+
|
16
|
+
end # namespace :bones
|
17
|
+
|
18
|
+
end # HAVE_BONES
|
19
|
+
|
20
|
+
# EOF
|