subtrigger 0.2.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/.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
|