olag 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +24 -0
- data/LICENSE +19 -0
- data/README.rdoc +17 -0
- data/Rakefile +24 -0
- data/codnar.html +4379 -0
- data/doc/root.html +26 -0
- data/doc/system.markdown +283 -0
- data/lib/olag/application.rb +167 -0
- data/lib/olag/change_log.rb +59 -0
- data/lib/olag/data_files.rb +20 -0
- data/lib/olag/errors.rb +44 -0
- data/lib/olag/gem_specification.rb +77 -0
- data/lib/olag/globals.rb +43 -0
- data/lib/olag/hash_struct.rb +12 -0
- data/lib/olag/rake.rb +263 -0
- data/lib/olag/string_unindent.rb +19 -0
- data/lib/olag/test.rb +8 -0
- data/lib/olag/test/with_errors.rb +26 -0
- data/lib/olag/test/with_fakefs.rb +36 -0
- data/lib/olag/test/with_rake.rb +34 -0
- data/lib/olag/test/with_tempfile.rb +49 -0
- data/lib/olag/update_version.rb +53 -0
- data/lib/olag/version.rb +8 -0
- data/test/access_data_files.rb +15 -0
- data/test/collect_errors.rb +33 -0
- data/test/missing_keys.rb +17 -0
- data/test/run_application.rb +44 -0
- data/test/unindent_text.rb +26 -0
- metadata +243 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
module Olag
|
2
|
+
|
3
|
+
# Create ChangeLog files based on the Git revision history.
|
4
|
+
class ChangeLog
|
5
|
+
|
6
|
+
# Write a changelog based on the Git log.
|
7
|
+
def initialize(path)
|
8
|
+
@subjects_by_id = {}
|
9
|
+
@sorted_ids = []
|
10
|
+
read_log_lines
|
11
|
+
File.open(path, "w") do |file|
|
12
|
+
@log_file = file
|
13
|
+
write_log_file
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
# Read all the log lines from Git's revision history.
|
20
|
+
def read_log_lines
|
21
|
+
IO.popen("git log --pretty='format:%ci::%an <%ae>::%s'", "r").each_line do |log_line|
|
22
|
+
load_log_line(log_line)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Load a single Git log line into memory.
|
27
|
+
def load_log_line(log_line)
|
28
|
+
id, subject = ChangeLog.parse_log_line(log_line)
|
29
|
+
@sorted_ids << id
|
30
|
+
@subjects_by_id[id] ||= []
|
31
|
+
@subjects_by_id[id] << subject
|
32
|
+
end
|
33
|
+
|
34
|
+
# Extract the information we need (ChangeLog entry id and subject) from a
|
35
|
+
# Git log line.
|
36
|
+
def self.parse_log_line(log_line)
|
37
|
+
date, author, subject = log_line.chomp.split("::")
|
38
|
+
date, time, zone = date.split(" ")
|
39
|
+
id = "#{date}\t#{author}"
|
40
|
+
return id, subject
|
41
|
+
end
|
42
|
+
|
43
|
+
# Write a ChangeLog file based on the read Git log lines.
|
44
|
+
def write_log_file
|
45
|
+
@sorted_ids.uniq.each do |id|
|
46
|
+
write_log_entry(id, @subjects_by_id[id])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Write a single ChaneLog entry.
|
51
|
+
def write_log_entry(id, subjects)
|
52
|
+
@log_file.puts "#{id}\n\n"
|
53
|
+
@log_file.puts subjects.map { |subject| "\t* #{subject}" }.join("\n")
|
54
|
+
@log_file.puts "\n"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Olag
|
2
|
+
|
3
|
+
# Provide access to data files packaged with the gem.
|
4
|
+
module DataFiles
|
5
|
+
|
6
|
+
# Given the name of a data file packaged in some gem, return the absolute
|
7
|
+
# disk path for accessing that data file. This is similar to what +require+
|
8
|
+
# does internally, but here we just want the path for reading data, rather
|
9
|
+
# than load the Ruby code in the file.
|
10
|
+
def self.expand_path(relative_path)
|
11
|
+
$LOAD_PATH.each do |load_directory|
|
12
|
+
absolute_path = File.expand_path(load_directory + "/" + relative_path)
|
13
|
+
return absolute_path if File.exist?(absolute_path)
|
14
|
+
end
|
15
|
+
return relative_path # This will cause "file not found error" down the line.
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/lib/olag/errors.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Olag
|
2
|
+
|
3
|
+
# Collect a list of errors.
|
4
|
+
class Errors < Array
|
5
|
+
|
6
|
+
# Create an empty errors collection.
|
7
|
+
def initialize
|
8
|
+
@path = nil
|
9
|
+
@line = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
# Associate all errors collected by a block with a specific disk file.
|
13
|
+
def in_path(path, &block)
|
14
|
+
prev_path, prev_line = @path, @line
|
15
|
+
@path, @line = path, nil
|
16
|
+
result = block.call
|
17
|
+
@path, @line = prev_path, prev_line
|
18
|
+
return result
|
19
|
+
end
|
20
|
+
|
21
|
+
# Set the line number for any errors collected from here on.
|
22
|
+
def at_line(line)
|
23
|
+
@line = line
|
24
|
+
end
|
25
|
+
|
26
|
+
# Add a single error to the collection, with automatic context annotation
|
27
|
+
# (current disk file and line). Other methods (push, += etc.) do not
|
28
|
+
# automatically add the context annotation.
|
29
|
+
def <<(message)
|
30
|
+
push(annotate_error_message(message))
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
# Annotate an error message with the context (current file and line).
|
36
|
+
def annotate_error_message(message)
|
37
|
+
return "#{$0}: #{message}" unless @path
|
38
|
+
return "#{$0}: #{message} in file: #{@path}" unless @line
|
39
|
+
return "#{$0}: #{message} in file: #{@path} at line: #{@line}"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Monkey-patch within the Gem module.
|
2
|
+
module Gem
|
3
|
+
|
4
|
+
# Enhanced automated gem specification.
|
5
|
+
class Specification
|
6
|
+
|
7
|
+
# The title of the gem for documentation (by default, the capitalized
|
8
|
+
# name).
|
9
|
+
attr_accessor :title
|
10
|
+
|
11
|
+
# The name of the file containing the gem's version (by default,
|
12
|
+
# <tt>lib/_name_/version.rb</tt>).
|
13
|
+
attr_accessor :version_file
|
14
|
+
|
15
|
+
alias_method :original_initialize, :initialize
|
16
|
+
|
17
|
+
# Create the gem specification. Requires a block to set up the basic gem
|
18
|
+
# information (name, version, author, email, description). In addition, the
|
19
|
+
# block may override default properties (e.g. title).
|
20
|
+
def initialize(&block)
|
21
|
+
original_initialize(&block)
|
22
|
+
setup_default_members
|
23
|
+
add_development_dependencies
|
24
|
+
setup_file_members
|
25
|
+
setup_rdoc
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set the new data members to their default values, unless they were
|
29
|
+
# already set by the gem specification block.
|
30
|
+
def setup_default_members
|
31
|
+
name = self.name
|
32
|
+
@title ||= name.capitalize
|
33
|
+
@version_file ||= "lib/#{name}/version.rb"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Add dependencies required for developing the gem.
|
37
|
+
def add_development_dependencies
|
38
|
+
add_dependency("olag") unless self.name == "olag"
|
39
|
+
%w(Saikuro codnar fakefs flay rake rcov rdoc reek roodi test-spec).each do |gem|
|
40
|
+
add_development_dependency(gem)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Initialize the standard gem specification file list members.
|
45
|
+
def setup_file_members
|
46
|
+
# These should cover all the gem's files, except for the extra rdoc
|
47
|
+
# files.
|
48
|
+
setup_file_member(:files, "{lib,doc}/**/*")
|
49
|
+
self.files << "Rakefile" << "codnar.html"
|
50
|
+
setup_file_member(:executables, "bin/*") { |path| path.sub("bin/", "") }
|
51
|
+
setup_file_member(:test_files, "test/**/*")
|
52
|
+
end
|
53
|
+
|
54
|
+
# Initialize a standard gem specification file list member to the files
|
55
|
+
# matching a pattern. If a block is given, it is used to map the file
|
56
|
+
# paths. This will append to the file list member if it has already been
|
57
|
+
# set by the gem specification block.
|
58
|
+
def setup_file_member(member, pattern, &block)
|
59
|
+
old_value = instance_variable_get("@#{member}")
|
60
|
+
new_value = FileList[pattern].find_all { |path| File.file?(path) }
|
61
|
+
new_value.map!(&block) if block
|
62
|
+
instance_variable_set("@#{member}", old_value + new_value)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Setup RDOC options in the gem specification.
|
66
|
+
def setup_rdoc
|
67
|
+
self.extra_rdoc_files = [ "README.rdoc", "LICENSE", "ChangeLog" ]
|
68
|
+
self.rdoc_options << "--title" << "#{title} #{version}" \
|
69
|
+
<< "--main" << "README.rdoc" \
|
70
|
+
<< "--line-numbers" \
|
71
|
+
<< "--all" \
|
72
|
+
<< "--quiet"
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/lib/olag/globals.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Olag
|
2
|
+
|
3
|
+
# Save and restore the global variables when running an application inside a
|
4
|
+
# test.
|
5
|
+
class Globals
|
6
|
+
|
7
|
+
# Run some code without affecting the global state.
|
8
|
+
def self.without_changes(&block)
|
9
|
+
state = Globals.new
|
10
|
+
begin
|
11
|
+
return block.call
|
12
|
+
ensure
|
13
|
+
state.restore
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Restore the relevant global variables.
|
18
|
+
def restore
|
19
|
+
$stdin = Globals.restore_file($stdin, @original_stdin)
|
20
|
+
$stdout = Globals.restore_file($stdout, @original_stdout)
|
21
|
+
$stderr = Globals.restore_file($stderr, @original_stderr)
|
22
|
+
ARGV.replace(@original_argv)
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
# Take a snapshot of the relevant global variables.
|
28
|
+
def initialize
|
29
|
+
@original_stdin = $stdin
|
30
|
+
@original_stdout = $stdout
|
31
|
+
@original_stderr = $stderr
|
32
|
+
@original_argv = ARGV.dup
|
33
|
+
end
|
34
|
+
|
35
|
+
# Restore a specific global file variable to its original state.
|
36
|
+
def self.restore_file(current, original)
|
37
|
+
current.close unless current == original
|
38
|
+
return original
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Extend the core Hash class.
|
2
|
+
class Hash
|
3
|
+
|
4
|
+
# Provide OpenStruct/JavaScript-like implicit <tt>.key</tt> and
|
5
|
+
# <tt>.key=</tt> methods.
|
6
|
+
def method_missing(method, *arguments)
|
7
|
+
method = method.to_s
|
8
|
+
key = method.chomp("=")
|
9
|
+
return method == key ? self[key] : self[key] = arguments[0]
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/lib/olag/rake.rb
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
require "codnar/rake"
|
2
|
+
require "olag/change_log"
|
3
|
+
require "olag/gem_specification"
|
4
|
+
require "olag/update_version"
|
5
|
+
require "olag/version"
|
6
|
+
require "rake/clean"
|
7
|
+
require "rake/gempackagetask"
|
8
|
+
require "rake/rdoctask"
|
9
|
+
require "rake/testtask"
|
10
|
+
require "rcov/rcovtask"
|
11
|
+
require "reek/rake/task"
|
12
|
+
require "roodi"
|
13
|
+
|
14
|
+
module Olag
|
15
|
+
|
16
|
+
# Automate Rake task creation for a gem.
|
17
|
+
class Rake
|
18
|
+
|
19
|
+
# Define all the Rake tasks.
|
20
|
+
def initialize(spec)
|
21
|
+
@spec = spec
|
22
|
+
@ruby_sources = @spec.files.find_all { |file| file =~ /^Rakefile$|\.rb$/ }
|
23
|
+
@weave_configurations = [ :weave_include, :weave_named_chunk_with_containers ]
|
24
|
+
task(:default => :all)
|
25
|
+
define_all_task
|
26
|
+
CLOBBER << "saikuro"
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
# Define a task that does "everything".
|
32
|
+
def define_all_task
|
33
|
+
define_desc_task("Version, verify, document, package", :all => [ :version, :verify, :doc, :package ])
|
34
|
+
define_verify_task
|
35
|
+
define_doc_task
|
36
|
+
define_commit_task
|
37
|
+
# This is a problem. If the version number gets updated, GemPackageTask
|
38
|
+
# fails. This is better than if it used the old version number, I
|
39
|
+
# suppose, but not as nice as if it just used @spec.version everywhere.
|
40
|
+
# The solution for this is to do a dry run before doing the final +rake+
|
41
|
+
# +commit+, which is a good idea in general.
|
42
|
+
::Rake::GemPackageTask.new(@spec) { |package| }
|
43
|
+
end
|
44
|
+
|
45
|
+
# {{{ Verify gem functionality
|
46
|
+
|
47
|
+
# Define a task to verify everything is OK.
|
48
|
+
def define_verify_task
|
49
|
+
define_desc_task("Test, coverage, analyze code", :verify => [ :coverage, :analyze ])
|
50
|
+
define_desc_class("Test code covarage with RCov", Rcov::RcovTask, "coverage") { |task| Rake.configure_coverage_task(task) }
|
51
|
+
define_desc_class("Test code without coverage", ::Rake::TestTask, "test") { |task| Rake.configure_test_task(task) }
|
52
|
+
define_analyze_task
|
53
|
+
end
|
54
|
+
|
55
|
+
# Configure a task to run all tests and verify 100% coverage. This is
|
56
|
+
# cheating a bit, since it will not complain about files that are not
|
57
|
+
# reached at all from any of the tests.
|
58
|
+
def self.configure_coverage_task(task)
|
59
|
+
task.test_files = FileList["test/*.rb"]
|
60
|
+
task.libs << "lib" << "test/lib"
|
61
|
+
task.rcov_opts << "--failure-threshold" << "100" \
|
62
|
+
<< "--exclude" << "^/"
|
63
|
+
# Strangely, on some occasions, RCov crazily tries to compute coverage
|
64
|
+
# for files inside Ruby's gem repository. Excluding all absolute paths
|
65
|
+
# prevents this.
|
66
|
+
end
|
67
|
+
|
68
|
+
# Configure a task to just run the tests without verifying coverage.
|
69
|
+
def self.configure_test_task(task)
|
70
|
+
task.test_files = FileList["test/*.rb"]
|
71
|
+
task.libs << "lib" << "test/lib"
|
72
|
+
end
|
73
|
+
|
74
|
+
# }}}
|
75
|
+
|
76
|
+
# {{{ Analyze the source code
|
77
|
+
|
78
|
+
# Define a task to verify the source code is clean.
|
79
|
+
def define_analyze_task
|
80
|
+
define_desc_task("Analyze source code", :analyze => [ :reek, :roodi, :flay, :saikuro ])
|
81
|
+
define_desc_class("Check for smelly code with Reek", Reek::Rake::Task) { |task| configure_reek_task(task) }
|
82
|
+
define_desc_task("Check for smelly code with Roodi", :roodi) { run_roodi_task }
|
83
|
+
define_desc_task("Check for duplicated code with Flay", :flay) { run_flay_task }
|
84
|
+
define_desc_task("Check for complex code with Saikuro", :saikuro) { run_saikuro_task }
|
85
|
+
end
|
86
|
+
|
87
|
+
# Configure a task to ensure there are no code smells using Reek.
|
88
|
+
def configure_reek_task(task)
|
89
|
+
task.reek_opts << "--quiet"
|
90
|
+
task.source_files = @ruby_sources
|
91
|
+
end
|
92
|
+
|
93
|
+
# Run Roodi to ensure there are no code smells.
|
94
|
+
def run_roodi_task
|
95
|
+
runner = Roodi::Core::Runner.new
|
96
|
+
runner.config = "roodi.config" if File.exist?("roodi.config")
|
97
|
+
@ruby_sources.each { |ruby_source| runner.check_file(ruby_source) }
|
98
|
+
(errors = runner.errors).each { |error| puts(error) }
|
99
|
+
raise "Roodi found #{errors.size} errors." unless errors.empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
# Run Flay to ensure there are no duplicated code fragments.
|
103
|
+
def run_flay_task
|
104
|
+
dirs = %w(bin lib test/lib).find_all { |dir| File.exist?(dir) }
|
105
|
+
result = IO.popen("flay " + dirs.join(' '), "r").read.chomp
|
106
|
+
return if result == "Total score (lower is better) = 0\n"
|
107
|
+
puts(result)
|
108
|
+
raise "Flay found code duplication."
|
109
|
+
end
|
110
|
+
|
111
|
+
# Run Saikuro to ensure there are no overly complex functions.
|
112
|
+
def run_saikuro_task
|
113
|
+
dirs = %w(bin lib test).find_all { |dir| File.exist?(dir) }
|
114
|
+
system("saikuro -c -t -y 0 -e 10 -o saikuro/ -i #{dirs.join(' -i ')} > /dev/null")
|
115
|
+
result = File.read("saikuro/index_cyclo.html")
|
116
|
+
raise "Saikuro found complicated code." if result.include?("Errors and Warnings")
|
117
|
+
end
|
118
|
+
|
119
|
+
# }}}
|
120
|
+
|
121
|
+
# {{{ Generate RDoc documentation
|
122
|
+
|
123
|
+
# Define a task to build all the documentation.
|
124
|
+
def define_doc_task
|
125
|
+
desc "Generate all documentation"
|
126
|
+
task :doc => [ :rdoc, :codnar ]
|
127
|
+
::Rake::RDocTask.new { |task| configure_rdoc_task(task) }
|
128
|
+
define_codnar_task
|
129
|
+
end
|
130
|
+
|
131
|
+
# Configure a task to build the RDoc documentation.
|
132
|
+
def configure_rdoc_task(task)
|
133
|
+
task.rdoc_files += @ruby_sources.reject { |file| file =~ /^test|Rakefile/ } + [ "LICENSE", "README.rdoc" ]
|
134
|
+
task.main = "README.rdoc"
|
135
|
+
task.rdoc_dir = "rdoc"
|
136
|
+
task.options = @spec.rdoc_options
|
137
|
+
end
|
138
|
+
|
139
|
+
# }}}
|
140
|
+
|
141
|
+
# {{{ Generate Codnar documentation
|
142
|
+
|
143
|
+
# A set of file Regexp patterns and their matching Codnar configurations.
|
144
|
+
# All the gem files are matched agains these patterns, in order, and a
|
145
|
+
# Codnar::SplitTask is created for the first matching one. If the matching
|
146
|
+
# configuration list is empty, the file is not split. However, the file
|
147
|
+
# must match at least one of the patterns. The gem is expected to modify
|
148
|
+
# this array, if needed, before creating the Rake object.
|
149
|
+
CODNAR_CONFIGURATIONS = [
|
150
|
+
[
|
151
|
+
# Exclude the ChangeLog and generated codnar.html files from the
|
152
|
+
# generated documentation.
|
153
|
+
"ChangeLog|codnar\.html",
|
154
|
+
], [
|
155
|
+
# Configurations for splitting Ruby files. Using Sunlight makes for
|
156
|
+
# fast splitting but slow viewing. Using GVim is the reverse.
|
157
|
+
"Rakefile|.*\.rb|bin/.*",
|
158
|
+
"classify_source_code:ruby",
|
159
|
+
"format_code_gvim_css:ruby",
|
160
|
+
"classify_shell_comments",
|
161
|
+
"format_rdoc_comments",
|
162
|
+
"chunk_by_vim_regions",
|
163
|
+
], [
|
164
|
+
# Configurations for HTML documentation files.
|
165
|
+
".*\.html",
|
166
|
+
"split_html_documentation",
|
167
|
+
], [
|
168
|
+
# Configurations for Markdown documentation files.
|
169
|
+
".*\.markdown|.*\.md",
|
170
|
+
"split_markdown_documentation",
|
171
|
+
], [
|
172
|
+
# Configurations for RDOC documentation files.
|
173
|
+
"LICENSE|.*\.rdoc",
|
174
|
+
"split_rdoc_documentation",
|
175
|
+
],
|
176
|
+
]
|
177
|
+
|
178
|
+
# Define a task to build the Codnar documentation.
|
179
|
+
def define_codnar_task
|
180
|
+
@spec.files.each do |file|
|
181
|
+
configurations = Rake.split_configurations(file)
|
182
|
+
Codnar::Rake::SplitTask.new([ file ], configurations) unless configurations == []
|
183
|
+
end
|
184
|
+
Codnar::Rake::WeaveTask.new("doc/root.html", [ :weave_include, :weave_named_chunk_with_containers ])
|
185
|
+
end
|
186
|
+
|
187
|
+
# Find the Codnar split configurations for a file.
|
188
|
+
def self.split_configurations(file)
|
189
|
+
CODNAR_CONFIGURATIONS.each do |configurations|
|
190
|
+
regexp = configurations[0] = convert_to_regexp(configurations[0])
|
191
|
+
return configurations[1..-1] if regexp.match(file)
|
192
|
+
end
|
193
|
+
abort("No Codnar configuration for file: #{file}")
|
194
|
+
end
|
195
|
+
|
196
|
+
# Convert a string configuration pattern to a real Regexp.
|
197
|
+
def self.convert_to_regexp(regexp)
|
198
|
+
return regexp if Regexp == regexp
|
199
|
+
begin
|
200
|
+
return Regexp.new("^(#{regexp})$")
|
201
|
+
rescue
|
202
|
+
abort("Invalid pattern regexp: ^(#{regexp})$ error: #{$!}")
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# }}}
|
207
|
+
|
208
|
+
# {{{ Automate Git commit process
|
209
|
+
|
210
|
+
# Define a task that commit changes to Git.
|
211
|
+
def define_commit_task
|
212
|
+
define_desc_task("Git commit process", :commit => [ :all, :first_commit, :changelog, :second_commit ])
|
213
|
+
define_desc_task("Update version file from Git", :version) { update_version_file }
|
214
|
+
define_desc_task("Perform the 1st (main) Git commit", :first_commit) { run_git_first_commit }
|
215
|
+
define_desc_task("Perform the 2nd (amend) Git commit", :second_commit) { run_git_second_commit }
|
216
|
+
define_desc_task("Update ChangeLog from Git", :changelog) { Olag::ChangeLog.new("ChangeLog") }
|
217
|
+
end
|
218
|
+
|
219
|
+
# Update the content of the version file to contain the correct Git-derived
|
220
|
+
# build number.
|
221
|
+
def update_version_file
|
222
|
+
version_file = @spec.version_file
|
223
|
+
updated_version = Olag::Version::update(version_file)
|
224
|
+
abort("Updated gem version; re-run rake") if @spec.version.to_s != updated_version
|
225
|
+
end
|
226
|
+
|
227
|
+
# Run the first Git commit. The user will be given an editor to review the
|
228
|
+
# commit and enter a commit message.
|
229
|
+
def run_git_first_commit
|
230
|
+
raise "Git 1st commit failed" unless system("set +x; git commit")
|
231
|
+
end
|
232
|
+
|
233
|
+
# Run the second Git commit. This amends the first commit with the updated
|
234
|
+
# ChangeLog.
|
235
|
+
def run_git_second_commit
|
236
|
+
raise "Git 2nd commit failed" unless system("set +x; EDITOR=true git commit --amend ChangeLog")
|
237
|
+
end
|
238
|
+
|
239
|
+
# }}}
|
240
|
+
|
241
|
+
# {{{ Task utilities
|
242
|
+
|
243
|
+
# Define a new task with a description.
|
244
|
+
def define_desc_task(description, *parameters)
|
245
|
+
desc(description)
|
246
|
+
task(*parameters) do
|
247
|
+
yield(task) if block_given?
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# Define a new task using some class.
|
252
|
+
def define_desc_class(description, klass, *parameters)
|
253
|
+
desc(description)
|
254
|
+
klass.new(*parameters) do |task|
|
255
|
+
yield(task) if block_given?
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# }}}
|
260
|
+
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|