state_machine-audit_trail 0.1.3 → 0.1.4

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