subtrigger 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +56 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/bin/subtrigger +4 -0
- data/lib/subtrigger/email.rb +56 -0
- data/lib/subtrigger/repository.rb +124 -0
- data/lib/subtrigger/trigger.rb +60 -0
- data/lib/subtrigger.rb +85 -0
- data/subtrigger.gemspec +69 -0
- data/test/helper.rb +11 -0
- data/test/test_email.rb +39 -0
- data/test/test_repository.rb +41 -0
- data/test/test_subtrigger.rb +34 -0
- data/test/test_trigger.rb +37 -0
- metadata +95 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Arjan van der Gaag
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
= subtrigger
|
2
|
+
|
3
|
+
Subtrigger is a tiny tool for firing callback methods based on triggers in subversion log messages. This allows you to send out e-mail notifications after a commit, or take some other action based on keywords in Subversion's log messages.
|
4
|
+
|
5
|
+
Here's a quick example:
|
6
|
+
|
7
|
+
# use as post-commit hook in /path/to/repo/hooks
|
8
|
+
require 'subtrigger'
|
9
|
+
Subtrigger.on(/log: (\w+)/) { |matches, repo|
|
10
|
+
puts "#{repo.author} committed #{matches[0]} in revision #{repo.revision}"
|
11
|
+
}.run(*ARGV)
|
12
|
+
|
13
|
+
== Documentation
|
14
|
+
|
15
|
+
See the inline API documentation for descriptions and usage examples.
|
16
|
+
|
17
|
+
== Credits
|
18
|
+
|
19
|
+
Author:: Arjan van der Gaag
|
20
|
+
E-mail:: arjan@arjanvandergaag.nl
|
21
|
+
URL:: http://arjanvandergaag.nl
|
22
|
+
Source:: http://github.com/avdgaag/subtrigger
|
23
|
+
|
24
|
+
== Note on Patches/Pull Requests
|
25
|
+
|
26
|
+
* Fork the project.
|
27
|
+
* Make your feature addition or bug fix.
|
28
|
+
* Add tests for it. This is important so I don't break it in a
|
29
|
+
future version unintentionally.
|
30
|
+
* Commit, do not mess with rakefile, version, or history.
|
31
|
+
(if you want to have your own version, that is fine but bump version in a
|
32
|
+
commit by itself I can ignore when I pull)
|
33
|
+
* Send me a pull request. Bonus points for topic branches.
|
34
|
+
|
35
|
+
== Copyright
|
36
|
+
|
37
|
+
Copyright (c) 2010 Arjan van der Gaag
|
38
|
+
|
39
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
40
|
+
a copy of this software and associated documentation files (the
|
41
|
+
"Software"), to deal in the Software without restriction, including
|
42
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
43
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
44
|
+
permit persons to whom the Software is furnished to do so, subject to
|
45
|
+
the following conditions:
|
46
|
+
|
47
|
+
The above copyright notice and this permission notice shall be
|
48
|
+
included in all copies or substantial portions of the Software.
|
49
|
+
|
50
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
51
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
52
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
53
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
54
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
55
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
56
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "subtrigger"
|
8
|
+
gem.summary = %Q{Create post-commit triggers for Subversion commit messages}
|
9
|
+
gem.description = %Q{This gem allows you to create simple Ruby triggers for Subversion commit messages, responding to keywords in your log messages to send e-mails, deploy sites or do whatever you need.}
|
10
|
+
gem.email = "arjan@arjanvandergaag.nl"
|
11
|
+
gem.homepage = "http://github.com/avdgaag/subtrigger"
|
12
|
+
gem.authors = ["Arjan van der Gaag"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
gem.add_development_dependency "mocha", ">= 0"
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "subtrigger #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
data/bin/subtrigger
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
module Subtrigger
|
2
|
+
# = E-mail notifications
|
3
|
+
#
|
4
|
+
# Sometimes you want to send notification e-mails after the hook has fired
|
5
|
+
# to inform developers or yourself of some event. This class is a simple
|
6
|
+
# wrapper around the standard +sendmail+ program.
|
7
|
+
#
|
8
|
+
# == Usage example
|
9
|
+
#
|
10
|
+
# Email.new(:to => 'john@cleese.com',
|
11
|
+
# :from => 'eric@idle.com',
|
12
|
+
# :subject => 'Fired',
|
13
|
+
# :body => 'Your post-commit hook has just fired').send
|
14
|
+
#
|
15
|
+
# If +sendmail+ can not be found on your system an exception will be raised.
|
16
|
+
#--
|
17
|
+
# TODO: Use a hash of options rather than plain arguments.
|
18
|
+
class Email
|
19
|
+
attr_accessor :from, :to, :subject, :body, :development
|
20
|
+
|
21
|
+
# Sets up a new message and tries to find +sendmail+ on your system.
|
22
|
+
def initialize(options = {})
|
23
|
+
@to = options[:to]
|
24
|
+
@from = options[:from]
|
25
|
+
@subject = options[:subject]
|
26
|
+
@body = options[:body]
|
27
|
+
@development = options[:development] || false
|
28
|
+
@sendmail = `which sendmail`.strip
|
29
|
+
raise 'Could not find sendmail; aborting.' if @sendmail.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Tries to use +sendmail+ to send the message.
|
33
|
+
def send
|
34
|
+
message = header + "\n" + body
|
35
|
+
unless development
|
36
|
+
fd = open("|#{@sendmail} #{@to}", "w")
|
37
|
+
fd.print(message)
|
38
|
+
fd.close
|
39
|
+
end
|
40
|
+
message
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def header
|
46
|
+
<<-EOS
|
47
|
+
To: #{@to}
|
48
|
+
From: #{@from}
|
49
|
+
Subject: [svn] #{@subject}
|
50
|
+
MIME-version: 1.0
|
51
|
+
Content-Type: text/plain; charset=UTF-8
|
52
|
+
Content-Transfer-Encoding: 8bit
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Subtrigger
|
2
|
+
# = Subversion repostitory wrapper
|
3
|
+
#
|
4
|
+
# Use this class to get to the information for a specific commit in a
|
5
|
+
# specific subversion repository. This is a simple wrapper around the
|
6
|
+
# +svnlook+ command.
|
7
|
+
#
|
8
|
+
# This class will look for +svn+ and +svnlook+ on your system and will raise
|
9
|
+
# an exception when it can not be found.
|
10
|
+
#
|
11
|
+
# == Usage example
|
12
|
+
#
|
13
|
+
# repo = Repository.new('/path/to/repo', 5540)
|
14
|
+
# repo.author # => 'Graham'
|
15
|
+
# repo.message # => 'Added copyright information to the readme'
|
16
|
+
# repo.changed_projects do |p|
|
17
|
+
# puts p # => a changed directory above a trunk, branches or tags
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
class Repository
|
21
|
+
attr_reader :path, :revision
|
22
|
+
|
23
|
+
# Initialize a new wrapper around a repository at a given revision.
|
24
|
+
#
|
25
|
+
# This will try to find the +svn+ executable on your system and raise
|
26
|
+
# an exception when it cannot be found.
|
27
|
+
#
|
28
|
+
# Exceptions will also be raised when the repository path can not be
|
29
|
+
# found or the revision is not numeric.
|
30
|
+
def initialize(path, revision)
|
31
|
+
raise "Repository '#{path}' not found" unless File.directory?(path)
|
32
|
+
raise "Invalid revision number '#{revision}'" unless revision.to_i > 0
|
33
|
+
@path = path
|
34
|
+
@revision = revision.to_i
|
35
|
+
@svn_path = `which svn`.strip
|
36
|
+
raise 'Could not locate svn' if @svn_path.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return the path to the current repository. If given an extra string,
|
40
|
+
# that will be appended to the path.
|
41
|
+
#
|
42
|
+
# Example:
|
43
|
+
#
|
44
|
+
# repo.path # => '/path/to/repo'
|
45
|
+
# repo.path('mydir') # => '/path/to/repo/mydir'
|
46
|
+
#
|
47
|
+
def path(subpath = nil)
|
48
|
+
return File.join(@path, subpath) unless subpath.nil?
|
49
|
+
@path
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the information from <tt>svnlook changed</tt>.
|
53
|
+
def changed
|
54
|
+
@changed ||= look_at('changed')
|
55
|
+
end
|
56
|
+
|
57
|
+
# Yields all directories above a changed trunk, branches or tags directory.
|
58
|
+
#
|
59
|
+
# Assuming a project layout like this:
|
60
|
+
#
|
61
|
+
# [root]
|
62
|
+
# |- project1
|
63
|
+
# |- project2
|
64
|
+
# |- group1
|
65
|
+
# `- project3
|
66
|
+
# |- branches
|
67
|
+
# |- tags
|
68
|
+
# `- trunk
|
69
|
+
#
|
70
|
+
# Then committing to <tt>group1/project3/trunk</tt> will yield both
|
71
|
+
# <tt>group1/project3/trunk</tt> and <tt>project3</tt>.
|
72
|
+
def changed_projects #:yields: full_path, project_path
|
73
|
+
(@dirs_changed ||= look_at('dirs-changed')).split("\n").each do |dir|
|
74
|
+
yield dir, $1 if dir =~ /([\w\-\.]+)\/(?:trunk|branches|tags)/
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the HEAD revision number (<tt>svnlook youngest</tt>)
|
79
|
+
def head
|
80
|
+
@head ||= look_at('youngest')
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the author of the last commit.
|
84
|
+
def author
|
85
|
+
@author ||= get_line_from_info(0)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the log message of the last commit.
|
89
|
+
def message
|
90
|
+
@message ||= get_line_from_info(3)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the date from the last commit.
|
94
|
+
def date
|
95
|
+
@date ||= get_line_from_info(1)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Runs an arbitrary +svn+ command and returns its results.
|
99
|
+
def exec(command)
|
100
|
+
command = "#{@svn_path} #{command}"
|
101
|
+
`#{command}`
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# Execute a +svnlook+ command for the current repository and revision.
|
107
|
+
def look_at(subcommand)
|
108
|
+
`#{File.join(File.dirname(@svn_path), 'svnlook')} #{subcommand} #{@path} -r #{@revision}`
|
109
|
+
end
|
110
|
+
|
111
|
+
# Get the contents of a line from the <tt>svnlook info</tt> output, which
|
112
|
+
# looks like this:
|
113
|
+
#
|
114
|
+
# Author name
|
115
|
+
# Commit date
|
116
|
+
# Log message length
|
117
|
+
# Log message
|
118
|
+
#
|
119
|
+
def get_line_from_info(n)
|
120
|
+
@info ||= look_at('info')
|
121
|
+
@info.split("\n")[n]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Subtrigger
|
2
|
+
# = Call blocks on a matching pattern
|
3
|
+
#
|
4
|
+
# This is a framework for combining pairs of matchers and callbacks to run
|
5
|
+
# on a commit message. You can define a trigger which this class will
|
6
|
+
# apply to a log message.
|
7
|
+
#
|
8
|
+
# == Example usage
|
9
|
+
#
|
10
|
+
# Trigger.define(/foo/) do |matches, repo|
|
11
|
+
# puts "Someone used 'foo' in his commit message"
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# When the above trigger is defined and somebody makes a commit message
|
15
|
+
# containing +foo+ the block will be called. +matches+ contains any
|
16
|
+
# captured regular expression groups, +repo+ is a +Repository+ object for
|
17
|
+
# the current repository revision.
|
18
|
+
#
|
19
|
+
# You can define as many triggers as you like. When no triggers are found
|
20
|
+
# an exception will be raised. When no trigger applies, it will quit
|
21
|
+
# silently.
|
22
|
+
class Trigger
|
23
|
+
class << self
|
24
|
+
@triggers = {}
|
25
|
+
|
26
|
+
# Run all available triggers on the given Repository object.
|
27
|
+
def run(repo)
|
28
|
+
raise 'No suitable triggers found.' if @triggers.nil?
|
29
|
+
@triggers.each_pair do |pattern, block|
|
30
|
+
new(pattern, repo, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def triggers
|
35
|
+
@triggers ||= {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset
|
39
|
+
@triggers = {}
|
40
|
+
end
|
41
|
+
|
42
|
+
# Create a new Trigger object and add it to the stack.
|
43
|
+
def define(pattern, &block)
|
44
|
+
(@triggers ||= {})[pattern] = block;
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(pattern, repo, &block)
|
49
|
+
@pattern, @repo, @callback = pattern, repo, block
|
50
|
+
parse
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Scan the commit message and fire the callback if it matches.
|
56
|
+
def parse
|
57
|
+
@repo.message.scan(@pattern) { |match| @callback.call(match, @repo) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/subtrigger.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
# = Subtrigger
|
3
|
+
#
|
4
|
+
# Subtrigger is a tiny tool for firing callback methods based on triggers in
|
5
|
+
# subversion log messages.
|
6
|
+
#
|
7
|
+
# == Example
|
8
|
+
#
|
9
|
+
# When somebody makes a commit:
|
10
|
+
#
|
11
|
+
# r5410 "Added a sitemap to the website [deploy]"
|
12
|
+
# A /www.website.tld/trunk/sitemap.xml
|
13
|
+
#
|
14
|
+
# ...then you can trigger the deployment of that project to a staging server
|
15
|
+
# using a +Trigger+:
|
16
|
+
#
|
17
|
+
# Subtrigger.on(/\[deploy\]/) do |matches, repo|
|
18
|
+
# # do some smart stuff here
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Your trigger has access to the captured groups in its regular expression
|
22
|
+
# matcher, and to all the <tt>svnlook</tt> information from the repository
|
23
|
+
# at the revision that fired the hook. This gives you access to changed paths,
|
24
|
+
# its author, date, etc.
|
25
|
+
#
|
26
|
+
# == E-mail notifications
|
27
|
+
#
|
28
|
+
# Subtrigger allows you to send notification e-mails to developers:
|
29
|
+
#
|
30
|
+
# # in your trigger:
|
31
|
+
# Subtrigger::Email.new(:to => "#{repo.author}@company.tld",
|
32
|
+
# :from => 'svn@company.tld',
|
33
|
+
# :subject => 'Trigger notification',
|
34
|
+
# :body => "Dear #{repo.author}, ...")
|
35
|
+
#
|
36
|
+
# == Usage
|
37
|
+
#
|
38
|
+
# This library is intended to be used as a Subversion post-commit hook.
|
39
|
+
# The best way to use it to create a post-commit hook file that requires this
|
40
|
+
# library, sets up one or more triggers and than fires the processing.
|
41
|
+
#
|
42
|
+
# Here's an example:
|
43
|
+
#
|
44
|
+
# #!/usr/local/bin/ruby
|
45
|
+
# require 'rubygems'
|
46
|
+
# require 'subtrigger'
|
47
|
+
# Subtrigger.on(/foo/) { |matches, repo|
|
48
|
+
# puts "#{repo.author} comitted foo!"
|
49
|
+
# }.on(/bar/) { |matches, repo|
|
50
|
+
# puts "#{repo.author} comitted bar!"
|
51
|
+
# }.run(*ARGV)
|
52
|
+
#
|
53
|
+
# Make sure your gems are installed and the correct permissions are set. Note
|
54
|
+
# that Subversion runs its hooks in an empty environment, with no PATH set,
|
55
|
+
# and you will also see no output.
|
56
|
+
module Subtrigger
|
57
|
+
# Output the version number for this gem by reading /VERSION
|
58
|
+
def self.version
|
59
|
+
File.read(File.join(File.dirname(__FILE__), *%w{.. VERSION}))
|
60
|
+
end
|
61
|
+
|
62
|
+
# This is the main spark in the program.
|
63
|
+
# It runs all available triggers on the repository object created with the
|
64
|
+
# two command line arguments: the path to the repository and its revision
|
65
|
+
# number.
|
66
|
+
#
|
67
|
+
# If an exception occurs, the program will quit with its error message.
|
68
|
+
def self.run(*args)
|
69
|
+
Trigger.run(Repository.new(*args))
|
70
|
+
rescue Exception => e
|
71
|
+
puts "Error: #{e}" and exit(1)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Define a new +Trigger+ object -- shortcut method to
|
75
|
+
# <tt>Trigger#define</tt>. To enable method chaining this method returns
|
76
|
+
# itself.
|
77
|
+
def self.on(pattern, &block)
|
78
|
+
Trigger.define(pattern, &block)
|
79
|
+
self
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
require 'subtrigger/email'
|
84
|
+
require 'subtrigger/trigger'
|
85
|
+
require 'subtrigger/repository'
|
data/subtrigger.gemspec
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{subtrigger}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Arjan van der Gaag"]
|
12
|
+
s.date = %q{2010-02-18}
|
13
|
+
s.default_executable = %q{subtrigger}
|
14
|
+
s.description = %q{This gem allows you to create simple Ruby triggers for Subversion commit messages, responding to keywords in your log messages to send e-mails, deploy sites or do whatever you need.}
|
15
|
+
s.email = %q{arjan@arjanvandergaag.nl}
|
16
|
+
s.executables = ["subtrigger"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".gitignore",
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/subtrigger",
|
29
|
+
"lib/subtrigger.rb",
|
30
|
+
"lib/subtrigger/email.rb",
|
31
|
+
"lib/subtrigger/repository.rb",
|
32
|
+
"lib/subtrigger/trigger.rb",
|
33
|
+
"subtrigger.gemspec",
|
34
|
+
"test/helper.rb",
|
35
|
+
"test/test_email.rb",
|
36
|
+
"test/test_repository.rb",
|
37
|
+
"test/test_subtrigger.rb",
|
38
|
+
"test/test_trigger.rb"
|
39
|
+
]
|
40
|
+
s.homepage = %q{http://github.com/avdgaag/subtrigger}
|
41
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = %q{1.3.5}
|
44
|
+
s.summary = %q{Create post-commit triggers for Subversion commit messages}
|
45
|
+
s.test_files = [
|
46
|
+
"test/helper.rb",
|
47
|
+
"test/test_email.rb",
|
48
|
+
"test/test_repository.rb",
|
49
|
+
"test/test_subtrigger.rb",
|
50
|
+
"test/test_trigger.rb"
|
51
|
+
]
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
55
|
+
s.specification_version = 3
|
56
|
+
|
57
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
58
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
59
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
62
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
63
|
+
end
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
66
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/test/helper.rb
ADDED
data/test/test_email.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestEmail < Test::Unit::TestCase
|
4
|
+
context 'with attributes' do
|
5
|
+
setup do
|
6
|
+
@email = Subtrigger::Email.new(
|
7
|
+
:to => 'to@to.com',
|
8
|
+
:from => 'from@from.com',
|
9
|
+
:subject => 'subject',
|
10
|
+
:body => 'body',
|
11
|
+
:development => true
|
12
|
+
)
|
13
|
+
@message = @email.send
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'set all e-mail attributes' do
|
17
|
+
assert_equal('from@from.com', @email.from)
|
18
|
+
assert_equal('to@to.com', @email.to)
|
19
|
+
assert_equal('subject', @email.subject)
|
20
|
+
assert_equal('body', @email.body)
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'use to address' do
|
24
|
+
assert_match(/From: from@from.com/, @message)
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'use from address' do
|
28
|
+
assert_match(/To: to@to.com/, @message)
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'use subject' do
|
32
|
+
assert_match(/Subject: \[svn\] subject/, @message)
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'use message body' do
|
36
|
+
assert_match(/body/, @message)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestRepository < Test::Unit::TestCase
|
4
|
+
should 'not work on non-existant repo' do
|
5
|
+
assert_raise(RuntimeError) { Subtrigger::Repository.new('foo', 'bar') }
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'for a repository' do
|
9
|
+
setup do
|
10
|
+
File.stubs(:directory?).returns(true)
|
11
|
+
@r = Subtrigger::Repository.new('path/to/repo', 1)
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'not work on illegal revision' do
|
15
|
+
assert_raise(RuntimeError) { Subtrigger::Repository.new('foo', 'bar') }
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'expand path' do
|
19
|
+
assert_equal('path/to/repo/foo', @r.path('foo'))
|
20
|
+
end
|
21
|
+
|
22
|
+
should 'use svnlook info' do
|
23
|
+
@r.expects(:look_at).with('info').returns('Foo')
|
24
|
+
assert_equal('Foo', @r.author)
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'yield changed directories' do
|
28
|
+
@r.expects(:look_at).with('dirs-changed').returns("www.project1.com/trunk\nsub/www.project2.com/tags/v1")
|
29
|
+
yieldings = [
|
30
|
+
['www.project1.com/trunk', 'www.project1.com'],
|
31
|
+
['sub/www.project2.com/tags/v1', 'www.project2.com']
|
32
|
+
]
|
33
|
+
i = 0
|
34
|
+
@r.changed_projects do |path, project|
|
35
|
+
assert_equal(yieldings[i][0], path)
|
36
|
+
assert_equal(yieldings[i][1], project)
|
37
|
+
i += 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSubtrigger < Test::Unit::TestCase
|
4
|
+
context 'with a clean slate' do
|
5
|
+
setup do
|
6
|
+
Subtrigger::Trigger.reset
|
7
|
+
end
|
8
|
+
|
9
|
+
should 'output the version number' do
|
10
|
+
assert_match(/\d+\.\d+\.\d+/, Subtrigger.version)
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'Create new Repository object' do
|
14
|
+
Subtrigger::Repository.expects(:new).with('foo', '1')
|
15
|
+
Subtrigger.run('foo', '1')
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'Run all triggers' do
|
19
|
+
Subtrigger::Repository.stubs(:new).returns('foo')
|
20
|
+
Subtrigger::Trigger.expects(:run).with('foo')
|
21
|
+
Subtrigger.run('foo', '1')
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'create a new trigger' do
|
25
|
+
assert_equal(0, Subtrigger::Trigger.triggers.size)
|
26
|
+
Subtrigger.on(/foo/) { |m,r| }
|
27
|
+
assert_equal(1, Subtrigger::Trigger.triggers.size)
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'chain creation of triggers' do
|
31
|
+
assert_equal(Subtrigger, Subtrigger.on(/foo/) { |m,r| })
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestTrigger < Test::Unit::TestCase
|
4
|
+
context 'in a clean state' do
|
5
|
+
setup do
|
6
|
+
Subtrigger::Trigger.reset
|
7
|
+
end
|
8
|
+
|
9
|
+
should 'define a new trigger' do
|
10
|
+
Subtrigger::Trigger.define(/foo/) { |m, r| raise 'bar' }
|
11
|
+
assert_equal(1, Subtrigger::Trigger.triggers.size)
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'apply all triggers' do
|
15
|
+
i = 0
|
16
|
+
Subtrigger::Trigger.define(/foo/) { |m,r| i += 1 }
|
17
|
+
Subtrigger::Trigger.define(/o+/) { |m,r| i += 1 }
|
18
|
+
Subtrigger::Trigger.run(stub(:message => 'foo bar'))
|
19
|
+
assert_equal(2, i)
|
20
|
+
end
|
21
|
+
|
22
|
+
should 'ignore unmatching triggers' do
|
23
|
+
i = 0
|
24
|
+
Subtrigger::Trigger.define(/foo/) { |m,r| i += 1 }
|
25
|
+
Subtrigger::Trigger.define(/x+/) { |m,r| i += 1 }
|
26
|
+
Subtrigger::Trigger.run(stub(:message => 'foo bar'))
|
27
|
+
assert_equal(1, i)
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'empty list of triggers' do
|
31
|
+
Subtrigger::Trigger.define(/foo/) { |m,r| }
|
32
|
+
assert_equal(1, Subtrigger::Trigger.triggers.size)
|
33
|
+
Subtrigger::Trigger.reset
|
34
|
+
assert_equal(0, Subtrigger::Trigger.triggers.size)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: subtrigger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Arjan van der Gaag
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-18 00:00:00 +01:00
|
13
|
+
default_executable: subtrigger
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mocha
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: This gem allows you to create simple Ruby triggers for Subversion commit messages, responding to keywords in your log messages to send e-mails, deploy sites or do whatever you need.
|
36
|
+
email: arjan@arjanvandergaag.nl
|
37
|
+
executables:
|
38
|
+
- subtrigger
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- .document
|
46
|
+
- .gitignore
|
47
|
+
- LICENSE
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- bin/subtrigger
|
52
|
+
- lib/subtrigger.rb
|
53
|
+
- lib/subtrigger/email.rb
|
54
|
+
- lib/subtrigger/repository.rb
|
55
|
+
- lib/subtrigger/trigger.rb
|
56
|
+
- subtrigger.gemspec
|
57
|
+
- test/helper.rb
|
58
|
+
- test/test_email.rb
|
59
|
+
- test/test_repository.rb
|
60
|
+
- test/test_subtrigger.rb
|
61
|
+
- test/test_trigger.rb
|
62
|
+
has_rdoc: true
|
63
|
+
homepage: http://github.com/avdgaag/subtrigger
|
64
|
+
licenses: []
|
65
|
+
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options:
|
68
|
+
- --charset=UTF-8
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.5
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Create post-commit triggers for Subversion commit messages
|
90
|
+
test_files:
|
91
|
+
- test/helper.rb
|
92
|
+
- test/test_email.rb
|
93
|
+
- test/test_repository.rb
|
94
|
+
- test/test_subtrigger.rb
|
95
|
+
- test/test_trigger.rb
|