corundum 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/README +2 -0
- data/doc/Specifications +6 -0
- data/doc/coverage/assets/0.5.3/app.js +88 -0
- data/doc/coverage/assets/0.5.3/fancybox/blank.gif +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_close.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_loading.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_nav_left.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_nav_right.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_e.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_n.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_ne.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_nw.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_s.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_se.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_sw.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_w.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_title_left.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_title_main.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_title_over.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancy_title_right.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancybox-x.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancybox-y.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/fancybox.png +0 -0
- data/doc/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.css +363 -0
- data/doc/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
- data/doc/coverage/assets/0.5.3/favicon_green.png +0 -0
- data/doc/coverage/assets/0.5.3/favicon_red.png +0 -0
- data/doc/coverage/assets/0.5.3/favicon_yellow.png +0 -0
- data/doc/coverage/assets/0.5.3/highlight.css +129 -0
- data/doc/coverage/assets/0.5.3/highlight.pack.js +1 -0
- data/doc/coverage/assets/0.5.3/jquery-1.6.2.min.js +18 -0
- data/doc/coverage/assets/0.5.3/jquery.dataTables.min.js +152 -0
- data/doc/coverage/assets/0.5.3/jquery.timeago.js +141 -0
- data/doc/coverage/assets/0.5.3/jquery.url.js +174 -0
- data/doc/coverage/assets/0.5.3/loading.gif +0 -0
- data/doc/coverage/assets/0.5.3/magnify.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/doc/coverage/assets/0.5.3/smoothness/jquery-ui-1.8.4.custom.css +295 -0
- data/doc/coverage/assets/0.5.3/stylesheet.css +383 -0
- data/doc/coverage/index.html +6511 -0
- data/lib/corundum.rb +130 -0
- data/lib/corundum/email.rb +92 -0
- data/lib/corundum/gem_building.rb +34 -0
- data/lib/corundum/gemcutter.rb +110 -0
- data/lib/corundum/gemspec_sanity.rb +32 -0
- data/lib/corundum/rspec.rb +135 -0
- data/lib/corundum/rubyforge.rb +95 -0
- data/lib/corundum/simplecov.rb +123 -0
- data/lib/corundum/tasklib.rb +57 -0
- data/lib/corundum/tasklibs.rb +8 -0
- data/lib/corundum/version_control.rb +36 -0
- data/lib/corundum/version_control/monotone.rb +126 -0
- data/lib/corundum/yardoc.rb +33 -0
- data/spec/bogus_spec.rb +3 -0
- data/spec/smoking_spec.rb +29 -0
- data/spec_help/file-sandbox.rb +164 -0
- data/spec_help/gem_test_suite.rb +17 -0
- data/spec_help/spec_helper.rb +4 -0
- data/spec_help/ungemmer.rb +36 -0
- metadata +292 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'corundum/tasklib'
|
2
|
+
|
3
|
+
|
4
|
+
#Big XXX: this totally isn't done. It's some notes against ever wanting to
|
5
|
+
#publish announcements to rubyforge ever again
|
6
|
+
|
7
|
+
module Corundum
|
8
|
+
class Publishing < TaskLib
|
9
|
+
def default_namespace
|
10
|
+
:email
|
11
|
+
end
|
12
|
+
|
13
|
+
def receive_tasklibs(toolkit)
|
14
|
+
@toolkit = toolkit
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_configuration(namespace, toolkit_config)
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(ns = :publish)
|
21
|
+
@ns = ns
|
22
|
+
@rubyforge = OpenStruct.new(:package_id => nil, :group_id => nil, :release_name => nil)
|
23
|
+
@package_dir = nil
|
24
|
+
@gemspec = nil
|
25
|
+
yield self if block_given?
|
26
|
+
define
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :ns, :rubyforge, :package_dir, :gemspec
|
30
|
+
|
31
|
+
def define
|
32
|
+
desc "Publish the gem and its documentation to Rubyforge and Gemcutter"
|
33
|
+
task @ns => ["#{@ns.to_s}:docs", "#{@ns.to_s}:rubyforge"]
|
34
|
+
|
35
|
+
namespace @ns do
|
36
|
+
desc 'Publish RDoc to RubyForge'
|
37
|
+
task :docs do
|
38
|
+
config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
|
39
|
+
host = "#{config["username"]}@rubyforge.org"
|
40
|
+
remote_dir = "/var/www/gforge-projects/#{@rubyforge[:group_id]}"
|
41
|
+
local_dir = 'rubydoc'
|
42
|
+
sh %{rsync -av --delete #{local_dir}/ #{host}:#{remote_dir}}
|
43
|
+
end
|
44
|
+
|
45
|
+
task :scrape_rubyforge do
|
46
|
+
require 'rubyforge'
|
47
|
+
forge = RubyForge.new
|
48
|
+
forge.configure
|
49
|
+
forge.scrape_project(@rubyforge[:package_id])
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Publishes to RubyForge"
|
53
|
+
task :rubyforge => [:docs, :scrape_rubyforge] do |t|
|
54
|
+
require 'rubyforge'
|
55
|
+
forge = RubyForge.new
|
56
|
+
forge.configure
|
57
|
+
files = [".gem", ".tar.gz", ".tar.bz2"].map do |extension|
|
58
|
+
File::join(@package_dir, @gemspec.full_name) + extension
|
59
|
+
end
|
60
|
+
release = forge.lookup("release", @rubyforge[:package_id])[@rubyforge[:release_name]] rescue nil
|
61
|
+
if release.nil?
|
62
|
+
forge.add_release(@rubyforge[:group_id], @rubyforge[:package_id], @rubyforge[:release_name], *files)
|
63
|
+
else
|
64
|
+
files.each do |file|
|
65
|
+
forge.add_file(@rubyforge[:group_id], @rubyforge[:package_id], @rubyforge[:release_name], file)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
module Corundum
|
77
|
+
class Email < TaskLib
|
78
|
+
def define
|
79
|
+
desc 'Announce release on RubyForge and email'
|
80
|
+
task @configuration.namespace => ["#{@configuration.namespace.to_s}:rubyforge", "#{@configuration.namespace.to_s}:email"]
|
81
|
+
namespace @configuration.namespace do
|
82
|
+
desc 'Post announcement to rubyforge.'
|
83
|
+
task :rubyforge do
|
84
|
+
require 'rubyforge'
|
85
|
+
subject, title, body = announcement
|
86
|
+
|
87
|
+
forge = RubyForge.new
|
88
|
+
forge.configure
|
89
|
+
forge.post_news(@configuration.rubyforge[:group_id], subject, "#{title}\n\n#{body}")
|
90
|
+
puts "Posted to rubyforge"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'corundum/tasklib'
|
2
|
+
|
3
|
+
module Corundum
|
4
|
+
class SimpleCov < TaskLib
|
5
|
+
def default_namespace
|
6
|
+
:coverage
|
7
|
+
end
|
8
|
+
|
9
|
+
def default_configuration(namespace, toolkit_config, testlib_config)
|
10
|
+
@configuration.namespace = namespace
|
11
|
+
@configuration.test_lib = nil
|
12
|
+
@configuration.browser = toolkit_config.browser
|
13
|
+
@configuration.report_dir = "doc/coverage"
|
14
|
+
@configuration.report_path = nil
|
15
|
+
@configuration.config_file = ".simplecov"
|
16
|
+
@configuration.config_path = nil
|
17
|
+
@configuration.filters = ["./spec"]
|
18
|
+
|
19
|
+
@configuration.threshold = 80
|
20
|
+
@configuration.files = OpenStruct.new(
|
21
|
+
:code => toolkit_config.files.code
|
22
|
+
)
|
23
|
+
@configuration.groups = {}
|
24
|
+
|
25
|
+
@configuration.all_files = toolkit_config.file_lists.code + toolkit_config.file_lists.test
|
26
|
+
end
|
27
|
+
|
28
|
+
def resolve_configuration
|
29
|
+
@configuration.config_path ||= File::expand_path(@configuration.config_file, Rake::original_dir)
|
30
|
+
@configuration.report_path ||= File::join(@configuration.report_dir, "index.html")
|
31
|
+
end
|
32
|
+
|
33
|
+
def receive_tasklibs(toolkit, test_lib)
|
34
|
+
@toolkit,@test_lib = toolkit, test_lib
|
35
|
+
end
|
36
|
+
|
37
|
+
def filters
|
38
|
+
@configuration.filters.map do |pattern|
|
39
|
+
"add_filter \"#{pattern}\""
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def groups
|
44
|
+
@configuration.groups.each_pair do |group, pattern|
|
45
|
+
"add_group \"#{group}\", \"#{pattern}\""
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def config_file_contents
|
50
|
+
contents = ["SimpleCov.start do"]
|
51
|
+
contents << " coverage_dir \"#{@configuration.report_dir}\""
|
52
|
+
contents += filters.map{|line| " " + line}
|
53
|
+
contents += groups.map{|line| " " + line}
|
54
|
+
contents << "end"
|
55
|
+
return contents.join("\n")
|
56
|
+
end
|
57
|
+
|
58
|
+
def define
|
59
|
+
in_namespace do
|
60
|
+
file "Rakefile"
|
61
|
+
|
62
|
+
task :example_config do
|
63
|
+
$stderr.puts "Try this in #{@configuration.config_path}"
|
64
|
+
$stderr.puts
|
65
|
+
puts config_file_contents
|
66
|
+
end
|
67
|
+
|
68
|
+
task :config_exists do
|
69
|
+
File::exists?(File::join(Rake::original_dir, ".simplecov")) or fail "No .simplecov"
|
70
|
+
end
|
71
|
+
|
72
|
+
directory File::dirname(@configuration.report_path)
|
73
|
+
file @configuration.report_path => @configuration.all_files do
|
74
|
+
options = @test_lib.custom_options do |options|
|
75
|
+
options.rspec_opts += %w{-r simplecov}
|
76
|
+
end
|
77
|
+
sh @test_lib.full_command(options)
|
78
|
+
end
|
79
|
+
|
80
|
+
task :generate_report => [:preflight, @configuration.report_path]
|
81
|
+
|
82
|
+
desc "View coverage in browser"
|
83
|
+
task :view => :generate_report do
|
84
|
+
sh "#{@configuration.browser} #{@configuration.report_path}"
|
85
|
+
end
|
86
|
+
|
87
|
+
task :verify_coverage => :generate_report do
|
88
|
+
require 'nokogiri'
|
89
|
+
|
90
|
+
doc = Nokogiri::parse(File::read(@configuration.report_path))
|
91
|
+
|
92
|
+
coverage_total_xpath = "//span[@class='covered_percent']/span"
|
93
|
+
percentage = doc.xpath(coverage_total_xpath).first.content.to_f
|
94
|
+
|
95
|
+
raise "Coverage must be at least #{@configuration.threshold} but was #{percentage}" if percentage < @configuration.threshold
|
96
|
+
puts "Coverage is #{percentage}% (required: #{@configuration.threshold}%)"
|
97
|
+
end
|
98
|
+
|
99
|
+
task :find_stragglers => :generate_report do
|
100
|
+
require 'nokogiri'
|
101
|
+
|
102
|
+
doc = Nokogiri::parse(File::read(@configuration.report_path))
|
103
|
+
|
104
|
+
covered_files = doc.xpath(
|
105
|
+
"//table[@class='file_list']//td//a[@class='src_link']").map do |link|
|
106
|
+
link.content
|
107
|
+
end
|
108
|
+
|
109
|
+
not_listed = covered_files - @configuration.files.code
|
110
|
+
not_covered = @configuration.files.code - covered_files
|
111
|
+
unless not_listed.empty? and not_covered.empty?
|
112
|
+
raise ["Covered files and gemspec manifest don't match:",
|
113
|
+
"Not in gemspec: #{not_listed.inspect}",
|
114
|
+
"Not covered: #{not_covered.inspect}"].join("\n")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
task :preflight => in_namespace(:config_exists)
|
119
|
+
|
120
|
+
task :qa => in_namespace(:verify_coverage, :find_stragglers)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
module Corundum
|
5
|
+
class TaskLib < Rake::TaskLib
|
6
|
+
attr_accessor :configuration
|
7
|
+
|
8
|
+
def receive_tasklibs(*tasklibs)
|
9
|
+
end
|
10
|
+
|
11
|
+
def default_configuration(namespace, *tasklib_configs)
|
12
|
+
end
|
13
|
+
|
14
|
+
def resolve_configuration
|
15
|
+
end
|
16
|
+
|
17
|
+
def in_namespace(*tasknames)
|
18
|
+
if tasknames.empty?
|
19
|
+
if block_given?
|
20
|
+
if @configuration.namespace.nil?
|
21
|
+
yield
|
22
|
+
else
|
23
|
+
namespace @configuration.namespace do
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
else
|
29
|
+
tasknames.map do |taskname|
|
30
|
+
[@configuration.namespace, taskname].compact.join(":")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_namespace
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(*tasklibs)
|
40
|
+
@configuration = OpenStruct.new(:namespace => default_namespace)
|
41
|
+
|
42
|
+
receive_tasklibs(*tasklibs)
|
43
|
+
|
44
|
+
configs = tasklibs.map do |tl|
|
45
|
+
tl.configuration
|
46
|
+
end
|
47
|
+
default_configuration(default_namespace, *configs)
|
48
|
+
|
49
|
+
|
50
|
+
yield @configuration if block_given?
|
51
|
+
|
52
|
+
resolve_configuration
|
53
|
+
|
54
|
+
define
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'corundum/tasklib'
|
2
|
+
|
3
|
+
module Corundum
|
4
|
+
class VersionControl < TaskLib
|
5
|
+
def default_namespace
|
6
|
+
:version_control
|
7
|
+
end
|
8
|
+
|
9
|
+
def receive_tasklibs(toolkit)
|
10
|
+
@toolkit = toolkit
|
11
|
+
end
|
12
|
+
|
13
|
+
def default_configuration(namespace, toolkit_config)
|
14
|
+
@configuration.namespace = namespace
|
15
|
+
@configuration.gemspec = toolkit_config.gemspec
|
16
|
+
@configuration.build_finished_file = toolkit_config.finished_files.build
|
17
|
+
@configuration.tag = toolkit_config.gemspec.version
|
18
|
+
end
|
19
|
+
|
20
|
+
def define
|
21
|
+
in_namespace do
|
22
|
+
task :not_tagged
|
23
|
+
task :is_checked_in
|
24
|
+
task :tag
|
25
|
+
task :check_in => :tag
|
26
|
+
end
|
27
|
+
|
28
|
+
task :preflight => in_namespace(:not_tagged)
|
29
|
+
task :build => in_namespace(:is_checked_in)
|
30
|
+
in_namespace(:tag, :check_in).each do |taskname|
|
31
|
+
task taskname => @configuration.build_finished_file
|
32
|
+
end
|
33
|
+
task :release => in_namespace(:tag, :check_in)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'corundum/version_control'
|
2
|
+
require 'strscan'
|
3
|
+
|
4
|
+
module Corundum
|
5
|
+
class Monotone < VersionControl
|
6
|
+
def default_namespace
|
7
|
+
:monotone
|
8
|
+
end
|
9
|
+
|
10
|
+
def default_configuration(*args)
|
11
|
+
super
|
12
|
+
@configuration.branch = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def resolve_configuration
|
16
|
+
@configuration.branch ||= guess_branch
|
17
|
+
end
|
18
|
+
|
19
|
+
def mtn_automate(cmd, *args)
|
20
|
+
result = ""
|
21
|
+
IO.popen("mtn automate #{cmd} #{args.join(" ")}") do |pipe|
|
22
|
+
result = pipe.read
|
23
|
+
end
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse_basic_io(string)
|
28
|
+
items = []
|
29
|
+
scanner = StringScanner.new(string)
|
30
|
+
scanner.scan(/\s*/m)
|
31
|
+
until scanner.eos? do
|
32
|
+
symbol = scanner.scan(/[a-z_]*/)
|
33
|
+
scanner.scan(/\s*/)
|
34
|
+
value = ""
|
35
|
+
case scanner.scan(/["\[]/)
|
36
|
+
when '"'
|
37
|
+
while (value += scanner.scan(/[^"]*/)) =~ /\\$/
|
38
|
+
end
|
39
|
+
scanner.scan(/"/)
|
40
|
+
when '['
|
41
|
+
value = scanner.scan(/[^\]]*/)
|
42
|
+
scanner.scan(/]/)
|
43
|
+
else
|
44
|
+
raise "Improperly formatted basic_io: \
|
45
|
+
\n Got: #{items.inspect} + #{symbol}\
|
46
|
+
\n Rest:\
|
47
|
+
\n #{scanner.rest}"
|
48
|
+
end
|
49
|
+
items << [symbol, value]
|
50
|
+
scanner.scan(/\s*/m)
|
51
|
+
end
|
52
|
+
return items
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_certs(string)
|
56
|
+
items = parse_basic_io(string)
|
57
|
+
pair = []
|
58
|
+
hash = Hash.new do |h,k|
|
59
|
+
h[k] = []
|
60
|
+
end
|
61
|
+
items.each do |name, value|
|
62
|
+
case name
|
63
|
+
when "name"
|
64
|
+
pair[0] = value
|
65
|
+
when "value"
|
66
|
+
pair[1] = value
|
67
|
+
when "trust"
|
68
|
+
if value == "trusted"
|
69
|
+
hash[pair[0]] << pair[1]
|
70
|
+
end
|
71
|
+
pair = []
|
72
|
+
end
|
73
|
+
end
|
74
|
+
hash
|
75
|
+
end
|
76
|
+
|
77
|
+
def base_revision
|
78
|
+
mtn_automate("get_base_revision_id")
|
79
|
+
end
|
80
|
+
|
81
|
+
def guess_branch
|
82
|
+
puts "Guessing branch - configure Monotone > branch"
|
83
|
+
certs = parse_certs(mtn_automate("certs", base_revision))
|
84
|
+
puts " Guessed: #{certs["branch"].first}"
|
85
|
+
certs["branch"].first
|
86
|
+
end
|
87
|
+
|
88
|
+
def define
|
89
|
+
super
|
90
|
+
|
91
|
+
in_namespace do
|
92
|
+
task :not_tagged do
|
93
|
+
items = parse_basic_io(mtn_automate("tags", @configuration.branch))
|
94
|
+
tags = items.find{|pair| pair[0] == "tag" && pair[1] == @configuration.tag}
|
95
|
+
unless tags.nil?
|
96
|
+
fail "Tag #{@configuration.tag} already exists in branch #{@configuration.branch}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
task :is_committed do
|
101
|
+
items = parse_basic_io(mtn_automate("inventory"))
|
102
|
+
changed = items.find{|pair| pair[0] == "changes"}
|
103
|
+
unless changed.nil?
|
104
|
+
fail "Uncommitted changes exist in workspace"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
task :tag do
|
109
|
+
mtn_automate("cert", base_revision, "tag", @configuration.tag)
|
110
|
+
end
|
111
|
+
|
112
|
+
task :commit do
|
113
|
+
run "mtn commit --branch #{@configuration.branch} --message \"Automatic commit: gem built at version #{@configuration.gemspec.version}\""
|
114
|
+
end
|
115
|
+
|
116
|
+
task :sync do
|
117
|
+
mtn_automate("sync")
|
118
|
+
end
|
119
|
+
|
120
|
+
task :check_in => %w{commit sync}
|
121
|
+
|
122
|
+
task :is_checked_in => [:is_committed]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|