state_machine-audit_trail 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,5 +1,12 @@
1
+ language: ruby
2
+ script: bundle exec rake
3
+ services: mongodb
1
4
  rvm:
2
5
  - 1.8.7
3
- - 1.9.2
4
6
  - 1.9.3
7
+ - 2.0.0
5
8
  - ree
9
+ - ruby-head
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
data/Rakefile CHANGED
@@ -1,4 +1,9 @@
1
- require File.expand_path('./tasks/github_gem', File.dirname(__FILE__))
2
- GithubGem::RakeTasks.new
1
+ require 'bundler/gem_tasks'
2
+ require "rspec/core/rake_task"
3
3
 
4
- task :default => [:spec]
4
+ RSpec::Core::RakeTask.new(:spec) do |task|
5
+ task.pattern = "./spec/**/*_spec.rb"
6
+ task.rspec_opts = ['--color']
7
+ end
8
+
9
+ task :default => [:spec]
@@ -2,13 +2,12 @@ require 'state_machine'
2
2
 
3
3
  module StateMachine::AuditTrail
4
4
 
5
- VERSION = "0.1.3"
6
-
7
5
  def self.setup
8
6
  StateMachine::Machine.send(:include, StateMachine::AuditTrail::TransitionAuditing)
9
7
  end
10
8
  end
11
9
 
10
+ require 'state_machine/audit_trail/version'
12
11
  require 'state_machine/audit_trail/transition_auditing'
13
12
  require 'state_machine/audit_trail/backend'
14
13
  require 'state_machine/audit_trail/railtie' if defined?(::Rails)
@@ -1,4 +1,4 @@
1
- class StateMachine::AuditTrail::Backend < Struct.new(:transition_class)
1
+ class StateMachine::AuditTrail::Backend < Struct.new(:transition_class, :owner_class)
2
2
 
3
3
  autoload :Mongoid, 'state_machine/audit_trail/backend/mongoid'
4
4
  autoload :ActiveRecord, 'state_machine/audit_trail/backend/active_record'
@@ -13,14 +13,14 @@ class StateMachine::AuditTrail::Backend < Struct.new(:transition_class)
13
13
  #
14
14
  # in order to adda new ORM here, copy audit_trail/mongoid.rb to whatever you want to call the new file and implement the #log function there
15
15
  # then, return from here the appropriate object based on which ORM the transition_class is using
16
- def self.create_for_transition_class(transition_class, context_to_log = nil)
16
+ def self.create_for_transition_class(transition_class, owner_class, context_to_log = nil)
17
17
  if Object.const_defined?('ActiveRecord') && transition_class.ancestors.include?(::ActiveRecord::Base)
18
- return StateMachine::AuditTrail::Backend::ActiveRecord.new(transition_class, context_to_log)
18
+ return StateMachine::AuditTrail::Backend::ActiveRecord.new(transition_class, owner_class, context_to_log)
19
19
  elsif Object.const_defined?('Mongoid') && transition_class.ancestors.include?(::Mongoid::Document)
20
20
  # Mongoid implementation doesn't yet support additional context fields
21
21
  raise NotImplemented, "Mongoid does not support additional context fields" if context_to_log.present?
22
22
 
23
- return StateMachine::AuditTrail::Backend::Mongoid.new(transition_class)
23
+ return StateMachine::AuditTrail::Backend::Mongoid.new(transition_class, owner_class)
24
24
  else
25
25
  raise NotImplemented, "Only support for ActiveRecord and Mongoid is included at this time"
26
26
  end
@@ -1,20 +1,18 @@
1
1
  class StateMachine::AuditTrail::Backend::ActiveRecord < StateMachine::AuditTrail::Backend
2
2
  attr_accessor :context_to_log
3
3
 
4
- def initialize(transition_class, context_to_log = nil)
4
+ def initialize(transition_class, owner_class, context_to_log = nil)
5
5
  self.context_to_log = context_to_log
6
+ @association = transition_class.to_s.tableize.to_sym
6
7
  super transition_class
8
+ owner_class.has_many @association
7
9
  end
8
10
 
9
11
  def log(object, event, from, to, timestamp = Time.now)
10
12
  # Let ActiveRecord manage the timestamp for us so it does the
11
13
  # right thing with regards to timezones.
12
- params = {foreign_key_field(object) => object.id, :event => event, :from => from, :to => to}
14
+ params = {:event => event, :from => from, :to => to}
13
15
  params[self.context_to_log] = object.send(self.context_to_log) unless self.context_to_log.nil?
14
- transition_class.create(params)
15
- end
16
-
17
- def foreign_key_field(object)
18
- object.class.base_class.name.foreign_key.to_sym
16
+ object.send(@association).create(params)
19
17
  end
20
18
  end
@@ -25,7 +25,7 @@ module StateMachine::AuditTrail::TransitionAuditing
25
25
 
26
26
  # Public returns an instance of the class which does the actual audit trail logging
27
27
  def audit_trail(context_to_log = nil)
28
- @transition_auditor ||= StateMachine::AuditTrail::Backend.create_for_transition_class(transition_class, context_to_log)
28
+ @transition_auditor ||= StateMachine::AuditTrail::Backend.create_for_transition_class(transition_class, self.owner_class, context_to_log)
29
29
  end
30
30
 
31
31
  private
@@ -0,0 +1,5 @@
1
+ module StateMachine
2
+ module AuditTrail
3
+ VERSION = "0.1.4"
4
+ end
5
+ end
@@ -4,10 +4,15 @@ require 'helpers/active_record'
4
4
  describe StateMachine::AuditTrail::Backend::ActiveRecord do
5
5
 
6
6
  it "should create an ActiveRecord backend" do
7
- backend = StateMachine::AuditTrail::Backend.create_for_transition_class(ActiveRecordTestModelStateTransition)
7
+ backend = StateMachine::AuditTrail::Backend.create_for_transition_class(ActiveRecordTestModelStateTransition, ActiveRecordTestModel)
8
8
  backend.should be_instance_of(StateMachine::AuditTrail::Backend::ActiveRecord)
9
9
  end
10
10
 
11
+ it "should create a has many association on the state machine owner" do
12
+ backend = StateMachine::AuditTrail::Backend.create_for_transition_class(ActiveRecordTestModelStateTransition, ActiveRecordTestModel)
13
+ ActiveRecordTestModel.reflect_on_association(:active_record_test_model_state_transitions).collection?.should be_true
14
+ end
15
+
11
16
  context 'on an object with a single state machine' do
12
17
  let!(:state_machine) { ActiveRecordTestModel.create! }
13
18
 
@@ -33,7 +38,7 @@ describe StateMachine::AuditTrail::Backend::ActiveRecord do
33
38
 
34
39
  context 'on an object with a single state machine that wants to log a single context' do
35
40
  before do
36
- backend = StateMachine::AuditTrail::Backend.create_for_transition_class(ActiveRecordTestModelWithContextStateTransition, :context)
41
+ backend = StateMachine::AuditTrail::Backend.create_for_transition_class(ActiveRecordTestModelWithContextStateTransition, ActiveRecordTestModelWithContext, :context)
37
42
  end
38
43
 
39
44
  let!(:state_machine) { ActiveRecordTestModelWithContext.create! }
@@ -4,7 +4,7 @@ require 'helpers/mongoid'
4
4
  describe StateMachine::AuditTrail::Backend::Mongoid do
5
5
 
6
6
  it "should create a Mongoid backend" do
7
- backend = StateMachine::AuditTrail::Backend.create_for_transition_class(MongoidTestModelStateTransition)
7
+ backend = StateMachine::AuditTrail::Backend.create_for_transition_class(MongoidTestModelStateTransition, MongoidTestModel)
8
8
  backend.should be_instance_of(StateMachine::AuditTrail::Backend::Mongoid)
9
9
  end
10
10
 
@@ -1,7 +1,12 @@
1
1
  # -*- encoding: utf-8 -*-
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'state_machine/audit_trail/version'
6
+
2
7
  Gem::Specification.new do |s|
3
8
  s.name = "state_machine-audit_trail"
4
- s.version = "0.1.3"
9
+ s.version = StateMachine::AuditTrail::VERSION
5
10
  s.platform = Gem::Platform::RUBY
6
11
  s.authors = ["Willem van Bergen", "Jesse Storimer"]
7
12
  s.email = ["willem@shopify.com", "jesse@shopify.com"]
@@ -20,6 +25,6 @@ Gem::Specification.new do |s|
20
25
  s.add_development_dependency('mongoid', '~> 2')
21
26
  s.add_development_dependency('bson_ext')
22
27
 
23
- s.files = %w(.gitignore .travis.yml Gemfile LICENSE README.rdoc Rakefile lib/state_machine-audit_trail.rb lib/state_machine/audit_trail.rb lib/state_machine/audit_trail/backend.rb lib/state_machine/audit_trail/backend/active_record.rb lib/state_machine/audit_trail/backend/mongoid.rb lib/state_machine/audit_trail/railtie.rb lib/state_machine/audit_trail/transition_auditing.rb lib/state_machine/audit_trail_generator.rb spec/helpers/active_record.rb spec/helpers/mongoid.rb spec/spec_helper.rb spec/state_machine/active_record_spec.rb spec/state_machine/audit_trail_spec.rb spec/state_machine/mongoid_spec.rb state_machine-audit_trail.gemspec tasks/github_gem.rb)
24
- s.test_files = %w(spec/state_machine/active_record_spec.rb spec/state_machine/audit_trail_spec.rb spec/state_machine/mongoid_spec.rb)
28
+ s.files = `git ls-files`.split($/)
29
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
25
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: state_machine-audit_trail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-08-28 00:00:00.000000000 Z
13
+ date: 2013-09-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: state_machine
17
- requirement: &70284895978760 !ruby/object:Gem::Requirement
17
+ requirement: &70300793098240 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70284895978760
25
+ version_requirements: *70300793098240
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rake
28
- requirement: &70284895977960 !ruby/object:Gem::Requirement
28
+ requirement: &70300793097260 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70284895977960
36
+ version_requirements: *70300793097260
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rspec
39
- requirement: &70284895976820 !ruby/object:Gem::Requirement
39
+ requirement: &70300793095100 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '2'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70284895976820
47
+ version_requirements: *70300793095100
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: activerecord
50
- requirement: &70284895976060 !ruby/object:Gem::Requirement
50
+ requirement: &70300793094400 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '3'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *70284895976060
58
+ version_requirements: *70300793094400
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: sqlite3
61
- requirement: &70284895954760 !ruby/object:Gem::Requirement
61
+ requirement: &70300793094020 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '0'
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *70284895954760
69
+ version_requirements: *70300793094020
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: mongoid
72
- requirement: &70284895954100 !ruby/object:Gem::Requirement
72
+ requirement: &70300793093260 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: '2'
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *70284895954100
80
+ version_requirements: *70300793093260
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: bson_ext
83
- requirement: &70284895953520 !ruby/object:Gem::Requirement
83
+ requirement: &70300793092540 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,7 +88,7 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *70284895953520
91
+ version_requirements: *70300793092540
92
92
  description: Log transitions on a state machine to support auditing and business process
93
93
  analytics.
94
94
  email:
@@ -111,6 +111,7 @@ files:
111
111
  - lib/state_machine/audit_trail/backend/mongoid.rb
112
112
  - lib/state_machine/audit_trail/railtie.rb
113
113
  - lib/state_machine/audit_trail/transition_auditing.rb
114
+ - lib/state_machine/audit_trail/version.rb
114
115
  - lib/state_machine/audit_trail_generator.rb
115
116
  - spec/helpers/active_record.rb
116
117
  - spec/helpers/mongoid.rb
@@ -119,7 +120,6 @@ files:
119
120
  - spec/state_machine/audit_trail_spec.rb
120
121
  - spec/state_machine/mongoid_spec.rb
121
122
  - state_machine-audit_trail.gemspec
122
- - tasks/github_gem.rb
123
123
  homepage: https://github.com/wvanbergen/state_machine-audit_trail
124
124
  licenses: []
125
125
  post_install_message:
@@ -146,6 +146,9 @@ specification_version: 3
146
146
  summary: Log transitions on a state machine to support auditing and business process
147
147
  analytics.
148
148
  test_files:
149
+ - spec/helpers/active_record.rb
150
+ - spec/helpers/mongoid.rb
151
+ - spec/spec_helper.rb
149
152
  - spec/state_machine/active_record_spec.rb
150
153
  - spec/state_machine/audit_trail_spec.rb
151
154
  - spec/state_machine/mongoid_spec.rb
data/tasks/github_gem.rb DELETED
@@ -1,367 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'rake/tasklib'
4
- require 'date'
5
- require 'set'
6
-
7
- module GithubGem
8
-
9
- # Detects the gemspc file of this project using heuristics.
10
- def self.detect_gemspec_file
11
- FileList['*.gemspec'].first
12
- end
13
-
14
- # Detects the main include file of this project using heuristics
15
- def self.detect_main_include
16
- if File.exist?(File.expand_path("../lib/#{File.basename(detect_gemspec_file, '.gemspec').gsub(/-/, '/')}.rb", detect_gemspec_file))
17
- "lib/#{File.basename(detect_gemspec_file, '.gemspec').gsub(/-/, '/')}.rb"
18
- elsif FileList['lib/*.rb'].length == 1
19
- FileList['lib/*.rb'].first
20
- else
21
- nil
22
- end
23
- end
24
-
25
- class RakeTasks
26
-
27
- include Rake::DSL if Rake.const_defined?('DSL')
28
-
29
- attr_reader :gemspec, :modified_files
30
- attr_accessor :gemspec_file, :task_namespace, :main_include, :root_dir, :spec_pattern, :test_pattern, :remote, :remote_branch, :local_branch
31
-
32
- # Initializes the settings, yields itself for configuration
33
- # and defines the rake tasks based on the gemspec file.
34
- def initialize(task_namespace = :gem)
35
- @gemspec_file = GithubGem.detect_gemspec_file
36
- @task_namespace = task_namespace
37
- @main_include = GithubGem.detect_main_include
38
- @modified_files = Set.new
39
- @root_dir = Dir.pwd
40
- @test_pattern = 'test/**/*_test.rb'
41
- @spec_pattern = 'spec/**/*_spec.rb'
42
- @local_branch = 'master'
43
- @remote = 'origin'
44
- @remote_branch = 'master'
45
-
46
- yield(self) if block_given?
47
-
48
- load_gemspec!
49
- define_tasks!
50
- end
51
-
52
- protected
53
-
54
- def git
55
- @git ||= ENV['GIT'] || 'git'
56
- end
57
-
58
- # Define Unit test tasks
59
- def define_test_tasks!
60
- require 'rake/testtask'
61
-
62
- namespace(:test) do
63
- Rake::TestTask.new(:basic) do |t|
64
- t.pattern = test_pattern
65
- t.verbose = true
66
- t.libs << 'test'
67
- end
68
- end
69
-
70
- desc "Run all unit tests for #{gemspec.name}"
71
- task(:test => ['test:basic'])
72
- end
73
-
74
- # Defines RSpec tasks
75
- def define_rspec_tasks!
76
- require 'rspec/core/rake_task'
77
-
78
- namespace(:spec) do
79
- desc "Verify all RSpec examples for #{gemspec.name}"
80
- RSpec::Core::RakeTask.new(:basic) do |t|
81
- t.pattern = spec_pattern
82
- end
83
-
84
- desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
85
- RSpec::Core::RakeTask.new(:specdoc) do |t|
86
- t.pattern = spec_pattern
87
- t.rspec_opts = ['--format', 'documentation', '--color']
88
- end
89
-
90
- desc "Run RCov on specs for #{gemspec.name}"
91
- RSpec::Core::RakeTask.new(:rcov) do |t|
92
- t.pattern = spec_pattern
93
- t.rcov = true
94
- t.rcov_opts = ['--exclude', '"spec/*,gems/*"', '--rails']
95
- end
96
- end
97
-
98
- desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
99
- task(:spec => ['spec:specdoc'])
100
- end
101
-
102
- # Defines the rake tasks
103
- def define_tasks!
104
-
105
- define_test_tasks! if has_tests?
106
- define_rspec_tasks! if has_specs?
107
-
108
- namespace(@task_namespace) do
109
- desc "Updates the filelist in the gemspec file"
110
- task(:manifest) { manifest_task }
111
-
112
- desc "Builds the .gem package"
113
- task(:build => :manifest) { build_task }
114
-
115
- desc "Sets the version of the gem in the gemspec"
116
- task(:set_version => [:check_version, :check_current_branch]) { version_task }
117
- task(:check_version => :fetch_origin) { check_version_task }
118
-
119
- task(:fetch_origin) { fetch_origin_task }
120
- task(:check_current_branch) { check_current_branch_task }
121
- task(:check_clean_status) { check_clean_status_task }
122
- task(:check_not_diverged => :fetch_origin) { check_not_diverged_task }
123
-
124
- checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
125
- checks.unshift('spec:basic') if has_specs?
126
- checks.unshift('test:basic') if has_tests?
127
- # checks.push << [:check_rubyforge] if gemspec.rubyforge_project
128
-
129
- desc "Perform all checks that would occur before a release"
130
- task(:release_checks => checks)
131
-
132
- release_tasks = [:release_checks, :set_version, :build, :github_release, :gemcutter_release]
133
- # release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
134
-
135
- desc "Release a new version of the gem using the VERSION environment variable"
136
- task(:release => release_tasks) { release_task }
137
-
138
- namespace(:release) do
139
- desc "Release the next version of the gem, by incrementing the last version segment by 1"
140
- task(:next => [:next_version] + release_tasks) { release_task }
141
-
142
- desc "Release the next version of the gem, using a patch increment (0.0.1)"
143
- task(:patch => [:next_patch_version] + release_tasks) { release_task }
144
-
145
- desc "Release the next version of the gem, using a minor increment (0.1.0)"
146
- task(:minor => [:next_minor_version] + release_tasks) { release_task }
147
-
148
- desc "Release the next version of the gem, using a major increment (1.0.0)"
149
- task(:major => [:next_major_version] + release_tasks) { release_task }
150
- end
151
-
152
- # task(:check_rubyforge) { check_rubyforge_task }
153
- # task(:rubyforge_release) { rubyforge_release_task }
154
- task(:gemcutter_release) { gemcutter_release_task }
155
- task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
156
- task(:tag_version) { tag_version_task }
157
- task(:commit_modified_files) { commit_modified_files_task }
158
-
159
- task(:next_version) { next_version_task }
160
- task(:next_patch_version) { next_version_task(:patch) }
161
- task(:next_minor_version) { next_version_task(:minor) }
162
- task(:next_major_version) { next_version_task(:major) }
163
-
164
- desc "Updates the gem release tasks with the latest version on Github"
165
- task(:update_tasks) { update_tasks_task }
166
- end
167
- end
168
-
169
- # Updates the files list and test_files list in the gemspec file using the list of files
170
- # in the repository and the spec/test file pattern.
171
- def manifest_task
172
- # Load all the gem's files using "git ls-files"
173
- repository_files = `#{git} ls-files`.split("\n")
174
- test_files = Dir[test_pattern] + Dir[spec_pattern]
175
-
176
- update_gemspec(:files, repository_files)
177
- update_gemspec(:test_files, repository_files & test_files)
178
- end
179
-
180
- # Builds the gem
181
- def build_task
182
- sh "gem build -q #{gemspec_file}"
183
- Dir.mkdir('pkg') unless File.exist?('pkg')
184
- sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
185
- end
186
-
187
- def newest_version
188
- `#{git} tag`.split("\n").map { |tag| tag.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max || Gem::Version.new('0.0.0')
189
- end
190
-
191
- def next_version(increment = nil)
192
- next_version = newest_version.segments
193
- increment_index = case increment
194
- when :micro then 3
195
- when :patch then 2
196
- when :minor then 1
197
- when :major then 0
198
- else next_version.length - 1
199
- end
200
-
201
- next_version[increment_index] ||= 0
202
- next_version[increment_index] = next_version[increment_index].succ
203
- ((increment_index + 1)...next_version.length).each { |i| next_version[i] = 0 }
204
-
205
- Gem::Version.new(next_version.join('.'))
206
- end
207
-
208
- def next_version_task(increment = nil)
209
- ENV['VERSION'] = next_version(increment).version
210
- puts "Releasing version #{ENV['VERSION']}..."
211
- end
212
-
213
- # Updates the version number in the gemspec file, the VERSION constant in the main
214
- # include file and the contents of the VERSION file.
215
- def version_task
216
- update_gemspec(:version, ENV['VERSION']) if ENV['VERSION']
217
- update_gemspec(:date, Date.today)
218
-
219
- update_version_file(gemspec.version)
220
- update_version_constant(gemspec.version)
221
- end
222
-
223
- def check_version_task
224
- raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
225
- proposed_version = Gem::Version.new((ENV['VERSION'] || gemspec.version).dup)
226
- raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version >= proposed_version
227
- end
228
-
229
- # Checks whether the current branch is not diverged from the remote branch
230
- def check_not_diverged_task
231
- raise "The current branch is diverged from the remote branch!" if `#{git} rev-list HEAD..#{remote}/#{remote_branch}`.split("\n").any?
232
- end
233
-
234
- # Checks whether the repository status ic clean
235
- def check_clean_status_task
236
- raise "The current working copy contains modifications" if `#{git} ls-files -m`.split("\n").any?
237
- end
238
-
239
- # Checks whether the current branch is correct
240
- def check_current_branch_task
241
- raise "Currently not on #{local_branch} branch!" unless `#{git} branch`.split("\n").detect { |b| /^\* / =~ b } == "* #{local_branch}"
242
- end
243
-
244
- # Fetches the latest updates from Github
245
- def fetch_origin_task
246
- sh git, 'fetch', remote
247
- end
248
-
249
- # Commits every file that has been changed by the release task.
250
- def commit_modified_files_task
251
- really_modified = `#{git} ls-files -m #{modified_files.entries.join(' ')}`.split("\n")
252
- if really_modified.any?
253
- really_modified.each { |file| sh git, 'add', file }
254
- sh git, 'commit', '-m', "Released #{gemspec.name} gem version #{gemspec.version}."
255
- end
256
- end
257
-
258
- # Adds a tag for the released version
259
- def tag_version_task
260
- sh git, 'tag', '-a', "#{gemspec.name}-#{gemspec.version}", '-m', "Released #{gemspec.name} gem version #{gemspec.version}."
261
- end
262
-
263
- # Pushes the changes and tag to github
264
- def github_release_task
265
- sh git, 'push', '--tags', remote, remote_branch
266
- end
267
-
268
- def gemcutter_release_task
269
- sh "gem", 'push', "pkg/#{gemspec.name}-#{gemspec.version}.gem"
270
- end
271
-
272
- # Gem release task.
273
- # All work is done by the task's dependencies, so just display a release completed message.
274
- def release_task
275
- puts
276
- puts "Release successful."
277
- end
278
-
279
- private
280
-
281
- # Checks whether this project has any RSpec files
282
- def has_specs?
283
- FileList[spec_pattern].any?
284
- end
285
-
286
- # Checks whether this project has any unit test files
287
- def has_tests?
288
- FileList[test_pattern].any?
289
- end
290
-
291
- # Loads the gemspec file
292
- def load_gemspec!
293
- @gemspec = eval(File.read(@gemspec_file))
294
- end
295
-
296
- # Updates the VERSION file with the new version
297
- def update_version_file(version)
298
- if File.exists?('VERSION')
299
- File.open('VERSION', 'w') { |f| f << version.to_s }
300
- modified_files << 'VERSION'
301
- end
302
- end
303
-
304
- # Updates the VERSION constant in the main include file if it exists
305
- def update_version_constant(version)
306
- if main_include && File.exist?(main_include)
307
- file_contents = File.read(main_include)
308
- if file_contents.sub!(/^(\s+VERSION\s*=\s*)[^\s].*$/) { $1 + version.to_s.inspect }
309
- File.open(main_include, 'w') { |f| f << file_contents }
310
- modified_files << main_include
311
- end
312
- end
313
- end
314
-
315
- # Updates an attribute of the gemspec file.
316
- # This function will open the file, and search/replace the attribute using a regular expression.
317
- def update_gemspec(attribute, new_value, literal = false)
318
-
319
- unless literal
320
- new_value = case new_value
321
- when Array then "%w(#{new_value.join(' ')})"
322
- when Hash, String then new_value.inspect
323
- when Date then new_value.strftime('%Y-%m-%d').inspect
324
- else raise "Cannot write value #{new_value.inspect} to gemspec file!"
325
- end
326
- end
327
-
328
- spec = File.read(gemspec_file)
329
- regexp = Regexp.new('^(\s+\w+\.' + Regexp.quote(attribute.to_s) + '\s*=\s*)[^\s].*$')
330
- if spec.sub!(regexp) { $1 + new_value }
331
- File.open(gemspec_file, 'w') { |f| f << spec }
332
- modified_files << gemspec_file
333
-
334
- # Reload the gemspec so the changes are incorporated
335
- load_gemspec!
336
-
337
- # Also mark the Gemfile.lock file as changed because of the new version.
338
- modified_files << 'Gemfile.lock' if File.exist?(File.join(root_dir, 'Gemfile.lock'))
339
- end
340
- end
341
-
342
- # Updates the tasks file using the latest file found on Github
343
- def update_tasks_task
344
- require 'net/https'
345
- require 'uri'
346
-
347
- uri = URI.parse('https://raw.github.com/wvanbergen/github-gem/master/tasks/github-gem.rake')
348
- http = Net::HTTP.new(uri.host, uri.port)
349
- http.use_ssl = true
350
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
351
- response = http.request(Net::HTTP::Get.new(uri.path))
352
-
353
- if Net::HTTPSuccess === response
354
- open(__FILE__, "w") { |file| file.write(response.body) }
355
- relative_file = File.expand_path(__FILE__).sub(%r[^#{@root_dir}/], '')
356
- if `#{git} ls-files -m #{relative_file}`.split("\n").any?
357
- sh git, 'add', relative_file
358
- sh git, 'commit', '-m', "Updated to latest gem release management tasks."
359
- else
360
- puts "Release managament tasks already are at the latest version."
361
- end
362
- else
363
- raise "Download failed with HTTP status #{response.code}!"
364
- end
365
- end
366
- end
367
- end