rails2ext 0.0.1
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/.gitignore +5 -0
- data/.rspec +1 -0
- data/CHANGELOG +2 -0
- data/Gemfile +4 -0
- data/README.md +13 -0
- data/Rakefile +8 -0
- data/lib/rails2ext.rb +7 -0
- data/lib/rails2ext/active_record.rb +3 -0
- data/lib/rails2ext/active_record/first_or_create.rb +5 -0
- data/lib/rails2ext/active_support.rb +5 -0
- data/lib/rails2ext/active_support/command_retry.rb +80 -0
- data/lib/rails2ext/active_support/core_ext.rb +1 -0
- data/lib/rails2ext/active_support/core_ext/array.rb +1 -0
- data/lib/rails2ext/active_support/core_ext/array/uniq_by.rb +11 -0
- data/lib/rails2ext/active_support/core_ext/load_error.rb +4 -0
- data/lib/rails2ext/active_support/quick_logger.rb +32 -0
- data/lib/rails2ext/version.rb +3 -0
- data/rails2ext.gemspec +27 -0
- data/spec/active_record/first_or_create_spec.rb +56 -0
- data/spec/active_support/command_retry_spec.rb +72 -0
- data/spec/active_support/core_ext/array/uniq_by_spec.rb +13 -0
- data/spec/active_support/core_ext/load_error_spec.rb +5 -0
- data/spec/active_support/quick_logger_spec.rb +44 -0
- data/spec/spec_helper.rb +6 -0
- metadata +165 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Rails2Ext
|
2
|
+
|
3
|
+
This gem is intended to collect all sort of **Rails 2.3.x** extensions that are not (yet?) present in the official repo.
|
4
|
+
Its structure mimic the original gems structure, so developers should feel at home browsing/extending it.
|
5
|
+
There is not much right now, but it could grow in size.
|
6
|
+
|
7
|
+
# Tests
|
8
|
+
|
9
|
+
Run
|
10
|
+
|
11
|
+
rake
|
12
|
+
|
13
|
+
to run the rspec test suite.
|
data/Rakefile
ADDED
data/lib/rails2ext.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# CommandRetry helps you repeat system commands when they
|
2
|
+
# are not successful for a given number of times (repeat
|
3
|
+
# once by default).
|
4
|
+
# If all repetitions fail, an error (default is
|
5
|
+
# RuntimeError) will be raised unless you passed in
|
6
|
+
# +:fail => false+ option
|
7
|
+
#
|
8
|
+
# It accepts also a +on+ option, which can be a single
|
9
|
+
# exit code or an array of exit codes that will cause
|
10
|
+
# the block to be repeated.
|
11
|
+
# Other exit codes not included in the +on+ array (if
|
12
|
+
# provided) will not cause repetitions and will will
|
13
|
+
# not raise errors.
|
14
|
+
#
|
15
|
+
# Will retry 5 times, failing each time and eventually
|
16
|
+
# raise the default error:
|
17
|
+
#
|
18
|
+
# CommandRetry.retry(:times => 5) { system 'bingobongo' }
|
19
|
+
# #=> RuntimeError: #<RuntimeError:0x101d89648>
|
20
|
+
#
|
21
|
+
# Will fail 5 times with exit code 7, eventually will
|
22
|
+
# raise custom error:
|
23
|
+
#
|
24
|
+
# CommandRetry.retry(:fail => ArgumentError, :on => 7 :times => 5) do
|
25
|
+
# system 'curl localhost:123/notfound'
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# Will fail just once since exit code 7 is not
|
29
|
+
# included in +on+ array, and will raise no error:
|
30
|
+
#
|
31
|
+
# CommandRetry.retry(:on => 52, :times => 5) do
|
32
|
+
# system 'curl localhost:123/notfound'
|
33
|
+
# end
|
34
|
+
|
35
|
+
class CommandRetry
|
36
|
+
def self.retry(opts={}, &block)
|
37
|
+
new(opts, &block).retry
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(opts={}, &block)
|
41
|
+
opts.symbolize_keys!
|
42
|
+
@times = opts[:times] || 2
|
43
|
+
@fail = opts[:fail] || RuntimeError unless opts[:fail] == false
|
44
|
+
@on = Array.wrap(opts[:on]) if opts[:on]
|
45
|
+
@command = block
|
46
|
+
end
|
47
|
+
|
48
|
+
def retry
|
49
|
+
result = false
|
50
|
+
status = 0
|
51
|
+
@times.times do
|
52
|
+
result = @command.call
|
53
|
+
status = exit_status
|
54
|
+
if should_break?(status)
|
55
|
+
break
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if @fail && status != 0
|
60
|
+
unless on_allows?(status)
|
61
|
+
raise @fail, caller
|
62
|
+
end
|
63
|
+
end
|
64
|
+
result
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def exit_status
|
70
|
+
$?.exitstatus
|
71
|
+
end
|
72
|
+
|
73
|
+
def should_break?(status)
|
74
|
+
status.zero? or on_allows?(status)
|
75
|
+
end
|
76
|
+
|
77
|
+
def on_allows?(status)
|
78
|
+
@on && !@on.include?(status)
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each { |filename| require filename }
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'array', 'uniq_by')
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
# quick and dirty logger: just inherit from here,
|
4
|
+
# set the filename attribute then you're ready to go
|
5
|
+
class QuickLogger
|
6
|
+
class << self
|
7
|
+
attr_accessor :filename
|
8
|
+
|
9
|
+
def filename_path
|
10
|
+
if defined?(Rails)
|
11
|
+
File.join Rails.root, 'log', [@filename, Rails.env, 'log'].join('.')
|
12
|
+
else
|
13
|
+
[@filename, 'log'].join('.')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(log_level, message)
|
18
|
+
@logger ||= ::Logger.new(filename_path)
|
19
|
+
if ::Logger::SEV_LABEL.include?(log_level.to_s.upcase)
|
20
|
+
@logger.send log_level, "[#{Time.now}] #{message}"
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# keep legacy interface
|
29
|
+
module Quick
|
30
|
+
class Logger < QuickLogger
|
31
|
+
end
|
32
|
+
end
|
data/rails2ext.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rails2ext/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rails2ext"
|
7
|
+
s.version = Rails2ext::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["andrea longhi"]
|
10
|
+
s.email = ["andrea@spaghetticode.it"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{some useful extensions for rails 2 apps}
|
13
|
+
s.description = %q{some useful extensions for rails 2 apps}
|
14
|
+
|
15
|
+
# s.rubyforge_project = "rails2ext"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_runtime_dependency 'rails', '~> 2.3.0'
|
23
|
+
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
s.add_development_dependency 'mocha'
|
26
|
+
s.add_development_dependency 'sqlite3'
|
27
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Person < ActiveRecord::Base
|
4
|
+
establish_connection :adapter => 'sqlite3', :database => ':memory:'
|
5
|
+
connection.create_table table_name, :force => true do |t|
|
6
|
+
t.string :name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe FirstOrCreate do
|
11
|
+
before { Person.delete_all }
|
12
|
+
|
13
|
+
context 'when no record matches given attributes' do
|
14
|
+
context 'when attributes are valid' do
|
15
|
+
let(:attributes) { {:name => 'Joe'} }
|
16
|
+
|
17
|
+
it 'should create a new record' do
|
18
|
+
expect do
|
19
|
+
Person.first_or_create!(attributes)
|
20
|
+
end.to change(Person, :count).by(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'created record should have requested attributes' do
|
24
|
+
Person.first_or_create!(attributes)
|
25
|
+
Person.find_by_name(attributes[:name]).should_not be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when attributes are not valid' do
|
30
|
+
let(:attributes) { {:surname => 'Doe'} }
|
31
|
+
|
32
|
+
it 'should raise an error' do
|
33
|
+
expect do
|
34
|
+
Person.first_or_create!(attributes)
|
35
|
+
end.to raise_error(ActiveRecord::StatementInvalid)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when a record matches given attributes' do
|
41
|
+
before do
|
42
|
+
@attributes = {:name => 'Joe'}
|
43
|
+
@joe = Person.create!(@attributes)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should return that record' do
|
47
|
+
Person.first_or_create!(@attributes).should == @joe
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should not create a new record' do
|
51
|
+
expect do
|
52
|
+
Person.first_or_create!(@attributes)
|
53
|
+
end.to_not change(Person, :count)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CommandRetry do
|
4
|
+
describe '#retry' do
|
5
|
+
context 'when command is successful' do
|
6
|
+
it 'should raise no error' do
|
7
|
+
command = CommandRetry.new {system 'echo'}
|
8
|
+
lambda {command.retry}.should_not raise_error
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when command is not successful' do
|
13
|
+
it 'should raise an error' do
|
14
|
+
command = CommandRetry.new {system 'will fail'}
|
15
|
+
lambda {command.retry}.should raise_error(RuntimeError)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when providing "times" option' do
|
19
|
+
subject { CommandRetry.new(:times => 5) {system 'will fail'} }
|
20
|
+
|
21
|
+
it 'should repeat operation, if not successful' do
|
22
|
+
subject.expects(:exit_status).times(5).returns(1)
|
23
|
+
subject.retry rescue nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when providing "fail" option' do
|
28
|
+
context 'when "fail" is a class' do
|
29
|
+
subject { CommandRetry.new(:fail => ArgumentError) {system 'will fail'} }
|
30
|
+
|
31
|
+
it 'should raise expected error' do
|
32
|
+
lambda {subject.retry}.should raise_error(ArgumentError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when "fail" is set to false' do
|
37
|
+
subject { CommandRetry.new(:fail => false) {system 'will fail'} }
|
38
|
+
|
39
|
+
it 'should raise no error' do
|
40
|
+
lambda {subject.retry}.should_not raise_error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when providing "on" option' do
|
46
|
+
subject { CommandRetry.new(:on => 42, :times => 3) {system 'will fail'} }
|
47
|
+
|
48
|
+
it 'should retry for given exit codes' do
|
49
|
+
subject.expects(:exit_status).times(3).returns(42)
|
50
|
+
subject.retry rescue nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should not raise error for other exit codes' do
|
54
|
+
subject.expects(:exit_status).times(1).returns(1)
|
55
|
+
lambda {subject.retry}.should_not raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should not retry for other exit codes' do
|
59
|
+
subject.expects(:exit_status).times(1).returns(1)
|
60
|
+
subject.retry
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '::retry' do
|
67
|
+
it 'should wrap initialization and retry process' do
|
68
|
+
CommandRetry.any_instance.expects(:retry)
|
69
|
+
CommandRetry.retry(:fail => false) {system 'ls'}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Array do
|
4
|
+
describe '#uniq_by' do
|
5
|
+
it 'should return an array' do
|
6
|
+
[].uniq_by {}.should be_an(Array)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should return unique values' do
|
10
|
+
[1, 2, 3, 4].uniq_by { |i| i.odd? }.should == [1, 2]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QuickLogger do
|
4
|
+
class TestLogger < QuickLogger; end
|
5
|
+
|
6
|
+
it 'should have filename accessor' do
|
7
|
+
filename = 'something_else'
|
8
|
+
TestLogger.filename = filename
|
9
|
+
TestLogger.filename.should == filename
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'filename_path' do
|
13
|
+
context 'when extending a rails app' do
|
14
|
+
before do
|
15
|
+
unless defined?(Rails)
|
16
|
+
module Rails; end
|
17
|
+
end
|
18
|
+
Rails.stubs(:env => 'test', :root => '/rails/rootpath')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should be in log dir, include rails env, have log extension' do
|
22
|
+
TestLogger.filename = 'some/path'
|
23
|
+
TestLogger.filename_path.should == '/rails/rootpath/log/some/path.test.log'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when used alone' do
|
28
|
+
before do
|
29
|
+
Object.send(:remove_const, :Rails) if defined?(Rails)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should match the plain filename' do
|
33
|
+
TestLogger.filename = 'other/path'
|
34
|
+
TestLogger.filename_path.should == 'other/path.log'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should respond to classic logger methods' do
|
40
|
+
lambda do
|
41
|
+
TestLogger.info "message"
|
42
|
+
end.should_not raise_error(NameError)
|
43
|
+
end
|
44
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails2ext
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- andrea longhi
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-07-11 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rails
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 3
|
31
|
+
- 0
|
32
|
+
version: 2.3.0
|
33
|
+
type: :runtime
|
34
|
+
requirement: *id001
|
35
|
+
prerelease: false
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
requirement: *id002
|
49
|
+
prerelease: false
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rspec
|
52
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :development
|
62
|
+
requirement: *id003
|
63
|
+
prerelease: false
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: mocha
|
66
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
requirement: *id004
|
77
|
+
prerelease: false
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: sqlite3
|
80
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
requirement: *id005
|
91
|
+
prerelease: false
|
92
|
+
description: some useful extensions for rails 2 apps
|
93
|
+
email:
|
94
|
+
- andrea@spaghetticode.it
|
95
|
+
executables: []
|
96
|
+
|
97
|
+
extensions: []
|
98
|
+
|
99
|
+
extra_rdoc_files: []
|
100
|
+
|
101
|
+
files:
|
102
|
+
- .gitignore
|
103
|
+
- .rspec
|
104
|
+
- CHANGELOG
|
105
|
+
- Gemfile
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- lib/rails2ext.rb
|
109
|
+
- lib/rails2ext/active_record.rb
|
110
|
+
- lib/rails2ext/active_record/first_or_create.rb
|
111
|
+
- lib/rails2ext/active_support.rb
|
112
|
+
- lib/rails2ext/active_support/command_retry.rb
|
113
|
+
- lib/rails2ext/active_support/core_ext.rb
|
114
|
+
- lib/rails2ext/active_support/core_ext/array.rb
|
115
|
+
- lib/rails2ext/active_support/core_ext/array/uniq_by.rb
|
116
|
+
- lib/rails2ext/active_support/core_ext/load_error.rb
|
117
|
+
- lib/rails2ext/active_support/quick_logger.rb
|
118
|
+
- lib/rails2ext/version.rb
|
119
|
+
- rails2ext.gemspec
|
120
|
+
- spec/active_record/first_or_create_spec.rb
|
121
|
+
- spec/active_support/command_retry_spec.rb
|
122
|
+
- spec/active_support/core_ext/array/uniq_by_spec.rb
|
123
|
+
- spec/active_support/core_ext/load_error_spec.rb
|
124
|
+
- spec/active_support/quick_logger_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
homepage: ""
|
127
|
+
licenses: []
|
128
|
+
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options: []
|
131
|
+
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
hash: 3
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
version: "0"
|
143
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
hash: 3
|
149
|
+
segments:
|
150
|
+
- 0
|
151
|
+
version: "0"
|
152
|
+
requirements: []
|
153
|
+
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 1.8.24
|
156
|
+
signing_key:
|
157
|
+
specification_version: 3
|
158
|
+
summary: some useful extensions for rails 2 apps
|
159
|
+
test_files:
|
160
|
+
- spec/active_record/first_or_create_spec.rb
|
161
|
+
- spec/active_support/command_retry_spec.rb
|
162
|
+
- spec/active_support/core_ext/array/uniq_by_spec.rb
|
163
|
+
- spec/active_support/core_ext/load_error_spec.rb
|
164
|
+
- spec/active_support/quick_logger_spec.rb
|
165
|
+
- spec/spec_helper.rb
|