drg 0.15.6 → 0.16.0
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.
- checksums.yaml +4 -4
- data/README.md +33 -60
- data/drg.gemspec +2 -4
- data/lib/drg/version.rb +1 -1
- data/lib/drg.rb +0 -3
- data/lib/tasks/drg.rake +0 -9
- metadata +5 -50
- data/lib/drg/decorators/sexp_decorator.rb +0 -20
- data/lib/drg/decorators.rb +0 -3
- data/lib/drg/ruby/assignment.rb +0 -25
- data/lib/drg/ruby/class_func.rb +0 -13
- data/lib/drg/ruby/condition.rb +0 -101
- data/lib/drg/ruby/const.rb +0 -100
- data/lib/drg/ruby/func.rb +0 -35
- data/lib/drg/ruby/instance_func.rb +0 -13
- data/lib/drg/ruby.rb +0 -21
- data/lib/drg/spec.rb +0 -115
- data/lib/drg/tasks/spec_runner.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3ec2da36e33e6a4ba09189233dd40b01401b1e7
|
4
|
+
data.tar.gz: 6e95adec97a178eedff8e6377ee4be64cdf3fd7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cec841fbfa30623d4edc7e534be902ebe919b4d9ce927822758f39cc6eea3ed411ca9c281f51b1da95b55669a2995405248742169de35d91051f022c9ae4210
|
7
|
+
data.tar.gz: 99cb20b249bed5bc2a089248fa88e2ece5c976f9618e34fceb7f635e3ff772de2fb971b705edfc7f0e751408a3058b615315722daee465bde781f5f204ecfc61
|
data/README.md
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
# DRG
|
2
|
+
[](https://codeclimate.com/github/ridiculous/drg)
|
2
3
|
[](http://badge.fury.io/rb/drg)
|
3
4
|
|
4
|
-
A
|
5
|
-
|
6
|
-
The `drg:pin` suite provides enhanced dependency management with Bundler. You can pin Gem versions to the current or the next
|
7
|
-
available minor, major or patch level version.
|
8
|
-
|
9
|
-
The `drg:spec` task generates RSpec scaffolding for existing code. This helps bootstrap your tests and guide you in what
|
10
|
-
you should be testing.
|
5
|
+
A Ruby utility to help automate dependency management using Bundler. You can pin Gem versions to the current or the next
|
6
|
+
available level.
|
11
7
|
|
12
8
|
## Requirements
|
13
9
|
|
@@ -22,7 +18,6 @@ gem 'drg'
|
|
22
18
|
## Tasks
|
23
19
|
|
24
20
|
```bash
|
25
|
-
rake drg:spec
|
26
21
|
rake drg:pin
|
27
22
|
rake drg:pin:major
|
28
23
|
rake drg:pin:minor
|
@@ -33,58 +28,6 @@ rake drg:pin:minor_latest
|
|
33
28
|
rake drg:unpin
|
34
29
|
```
|
35
30
|
|
36
|
-
### drg:spec
|
37
|
-
|
38
|
-
Generates RSpec scaffolding for existing code. Pass a file or directory and DRG will generate spec files for each:
|
39
|
-
|
40
|
-
```bash
|
41
|
-
rake drg:spec[app/controllers]
|
42
|
-
rake drg:spec[app/models/user.rb]
|
43
|
-
```
|
44
|
-
|
45
|
-
This task looks at your code's methods and breaks down their conditions into RSpec `context`s. For example:
|
46
|
-
|
47
|
-
Given this file:
|
48
|
-
|
49
|
-
```ruby
|
50
|
-
# app/models/ability.rb
|
51
|
-
class Ability
|
52
|
-
include CanCan::Ability
|
53
|
-
|
54
|
-
def initialize(user)
|
55
|
-
if user.admin?
|
56
|
-
can :manage, :all
|
57
|
-
else
|
58
|
-
can :read, :all
|
59
|
-
can :update, User do |u|
|
60
|
-
u.id == user.id
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
```
|
66
|
-
|
67
|
-
It will generate this spec:
|
68
|
-
```ruby
|
69
|
-
require "spec_helper"
|
70
|
-
|
71
|
-
describe Ability do
|
72
|
-
let(:user) {}
|
73
|
-
|
74
|
-
subject { described_class.new user }
|
75
|
-
|
76
|
-
describe "#initialize" do
|
77
|
-
context "when user.admin?" do
|
78
|
-
before {}
|
79
|
-
end
|
80
|
-
|
81
|
-
context "unless user.admin?" do
|
82
|
-
before {}
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
```
|
87
|
-
|
88
31
|
### drg:pin
|
89
32
|
|
90
33
|
DRG really wants to help you manage your project's gems. But DRG doesn't want to replace Bundler. Instead, we want to build on
|
@@ -198,6 +141,32 @@ Remove the versions from your Gemfile. A clean start!
|
|
198
141
|
rake drg:unpin
|
199
142
|
```
|
200
143
|
|
144
|
+
### Automation
|
145
|
+
|
146
|
+
I use the following bash script to update all gems to the latest [major|minor|patch] version, run all tests and then add
|
147
|
+
the result if the specs pass or rollback the changes if they fail.
|
148
|
+
|
149
|
+
```bash
|
150
|
+
#!/bin/bash
|
151
|
+
git add Gemfile
|
152
|
+
for cmd in $@; do
|
153
|
+
echo " * Updating $cmd versions"
|
154
|
+
bundle exec rake drg:pin:${cmd}_latest
|
155
|
+
bundle update
|
156
|
+
bundle exec rspec . -t ~js
|
157
|
+
if [ $? -eq 0 ]
|
158
|
+
then
|
159
|
+
echo " * Tests passed after updating $cmd versions. Adding Gemfile ..."
|
160
|
+
git add Gemfile*
|
161
|
+
else
|
162
|
+
echo " * Tests failed after updating $cmd versions. Reverting change to Gemfile ..." >&2
|
163
|
+
git checkout -- Gemfile*
|
164
|
+
bundle
|
165
|
+
exit 1
|
166
|
+
fi
|
167
|
+
done
|
168
|
+
```
|
169
|
+
|
201
170
|
### Skipping gems
|
202
171
|
|
203
172
|
You can tell drg to ignore gems by adding an inline comment with @drg (skip|ignore|frozen)
|
@@ -206,6 +175,10 @@ You can tell drg to ignore gems by adding an inline comment with @drg (skip|igno
|
|
206
175
|
gem 'name' # @drg skip
|
207
176
|
```
|
208
177
|
|
178
|
+
## Changes
|
179
|
+
|
180
|
+
Looking for `drg:spec` that does RSpec scaffolding? It's been moved to it's own gem: [rspec-scaffold](https://github.com/ridiculous/rspec-scaffold)
|
181
|
+
|
209
182
|
## Development
|
210
183
|
|
211
184
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests.
|
data/drg.gemspec
CHANGED
@@ -8,18 +8,16 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = DRG::VERSION
|
9
9
|
spec.authors = ["Ryan Buckley"]
|
10
10
|
spec.email = ["arebuckley@gmail.com"]
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{
|
11
|
+
spec.summary = %q{DRG that Gemfile! The missing bundler extension}
|
12
|
+
spec.description = %q{DRG that Gemfile! The missing bundler extension. Gem version automation with Bundler}
|
13
13
|
spec.homepage = "https://github.com/ridiculous/drg"
|
14
14
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
15
15
|
spec.executables = []
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
|
-
spec.add_dependency 'ruby_parser', '>= 3.7.0', '< 4.0.0'
|
19
18
|
spec.add_dependency 'bundler', '~> 1.10'
|
20
19
|
spec.add_dependency 'duck_puncher', '>= 2.0.0', '<= 3.0.0'
|
21
20
|
spec.add_dependency 'highline', '~> 1.7'
|
22
|
-
spec.add_dependency 'ruby2ruby', '~> 2.2'
|
23
21
|
|
24
22
|
spec.add_development_dependency 'rake', '~> 10.0'
|
25
23
|
spec.add_development_dependency 'rspec', '>= 3.2', '< 4'
|
data/lib/drg/version.rb
CHANGED
data/lib/drg.rb
CHANGED
data/lib/tasks/drg.rake
CHANGED
@@ -46,13 +46,4 @@ namespace :drg do
|
|
46
46
|
task latest_minor: :minor_latest
|
47
47
|
task latest_patch: :patch_latest
|
48
48
|
end
|
49
|
-
|
50
|
-
task :spec, [:file_name] => :environment do |_, args|
|
51
|
-
DRG::Tasks::SpecRunner.new(args.file_name).perform
|
52
|
-
end
|
53
|
-
|
54
|
-
unless defined?(Rails)
|
55
|
-
task :environment do
|
56
|
-
end
|
57
|
-
end
|
58
49
|
end
|
metadata
CHANGED
@@ -1,35 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Buckley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: ruby_parser
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 3.7.0
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 4.0.0
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 3.7.0
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 4.0.0
|
33
13
|
- !ruby/object:Gem::Dependency
|
34
14
|
name: bundler
|
35
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,20 +58,6 @@ dependencies:
|
|
78
58
|
- - "~>"
|
79
59
|
- !ruby/object:Gem::Version
|
80
60
|
version: '1.7'
|
81
|
-
- !ruby/object:Gem::Dependency
|
82
|
-
name: ruby2ruby
|
83
|
-
requirement: !ruby/object:Gem::Requirement
|
84
|
-
requirements:
|
85
|
-
- - "~>"
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version: '2.2'
|
88
|
-
type: :runtime
|
89
|
-
prerelease: false
|
90
|
-
version_requirements: !ruby/object:Gem::Requirement
|
91
|
-
requirements:
|
92
|
-
- - "~>"
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
version: '2.2'
|
95
61
|
- !ruby/object:Gem::Dependency
|
96
62
|
name: rake
|
97
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,8 +92,8 @@ dependencies:
|
|
126
92
|
- - "<"
|
127
93
|
- !ruby/object:Gem::Version
|
128
94
|
version: '4'
|
129
|
-
description:
|
130
|
-
|
95
|
+
description: DRG that Gemfile! The missing bundler extension. Gem version automation
|
96
|
+
with Bundler
|
131
97
|
email:
|
132
98
|
- arebuckley@gmail.com
|
133
99
|
executables: []
|
@@ -145,23 +111,12 @@ files:
|
|
145
111
|
- bin/setup
|
146
112
|
- drg.gemspec
|
147
113
|
- lib/drg.rb
|
148
|
-
- lib/drg/decorators.rb
|
149
|
-
- lib/drg/decorators/sexp_decorator.rb
|
150
|
-
- lib/drg/ruby.rb
|
151
|
-
- lib/drg/ruby/assignment.rb
|
152
|
-
- lib/drg/ruby/class_func.rb
|
153
|
-
- lib/drg/ruby/condition.rb
|
154
|
-
- lib/drg/ruby/const.rb
|
155
|
-
- lib/drg/ruby/func.rb
|
156
|
-
- lib/drg/ruby/instance_func.rb
|
157
|
-
- lib/drg/spec.rb
|
158
114
|
- lib/drg/tasks.rb
|
159
115
|
- lib/drg/tasks/active_pinner.rb
|
160
116
|
- lib/drg/tasks/gemfile.rb
|
161
117
|
- lib/drg/tasks/gemfile_line.rb
|
162
118
|
- lib/drg/tasks/log.rb
|
163
119
|
- lib/drg/tasks/pinner.rb
|
164
|
-
- lib/drg/tasks/spec_runner.rb
|
165
120
|
- lib/drg/tasks/updater.rb
|
166
121
|
- lib/drg/version.rb
|
167
122
|
- lib/tasks/drg.rake
|
@@ -187,5 +142,5 @@ rubyforge_project:
|
|
187
142
|
rubygems_version: 2.4.6
|
188
143
|
signing_key:
|
189
144
|
specification_version: 4
|
190
|
-
summary:
|
145
|
+
summary: DRG that Gemfile! The missing bundler extension
|
191
146
|
test_files: []
|
@@ -1,20 +0,0 @@
|
|
1
|
-
class DRG::Decorators::SexpDecorator < DelegateClass(Sexp)
|
2
|
-
def each_sexp_condition
|
3
|
-
return enum_for(__method__) unless block_given?
|
4
|
-
yielded = []
|
5
|
-
each_sexp do |exp|
|
6
|
-
if exp.first == :if
|
7
|
-
yield exp
|
8
|
-
yielded << exp
|
9
|
-
else
|
10
|
-
nested_sexp = exp.enum_for(:deep_each).select { |s| s.first == :if }
|
11
|
-
nested_sexp.each do |sexp|
|
12
|
-
if yielded.find { |x| x.object_id == sexp.object_id or x.enum_for(:deep_each).find { |xx| xx.object_id == sexp.object_id } }.nil?
|
13
|
-
yield sexp
|
14
|
-
yielded << sexp
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/drg/decorators.rb
DELETED
data/lib/drg/ruby/assignment.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module DRG
|
2
|
-
class Ruby
|
3
|
-
class Assignment
|
4
|
-
attr_reader :sexp
|
5
|
-
|
6
|
-
def initialize(sexp)
|
7
|
-
@sexp = sexp
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_s
|
11
|
-
"assigns #{ivar_name}"
|
12
|
-
end
|
13
|
-
|
14
|
-
# @example s(:iasgn, :@duder, s(:if, ...)
|
15
|
-
# @example s(:op_asgn_or, s(:ivar, :@report), ...)
|
16
|
-
def ivar_name
|
17
|
-
if sexp.first == :iasgn
|
18
|
-
sexp[1]
|
19
|
-
elsif sexp.first == :op_asgn_or
|
20
|
-
sexp[1][1]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/drg/ruby/class_func.rb
DELETED
data/lib/drg/ruby/condition.rb
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
require 'ruby2ruby'
|
2
|
-
|
3
|
-
class DRG::Ruby::Condition
|
4
|
-
|
5
|
-
module SetComparison
|
6
|
-
def eql?(other)
|
7
|
-
hash == other.hash
|
8
|
-
end
|
9
|
-
|
10
|
-
def hash
|
11
|
-
sexp.object_id
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
include SetComparison
|
16
|
-
|
17
|
-
attr_reader :statement, :nested_conditions, :sexp, :parts, :unless_found
|
18
|
-
|
19
|
-
def initialize(sexp)
|
20
|
-
@sexp = sexp
|
21
|
-
@statement = Ruby2Ruby.new.process(sexp.deep_clone)
|
22
|
-
@nested_conditions = create_nested_conditions
|
23
|
-
@parts = load_parts
|
24
|
-
end
|
25
|
-
|
26
|
-
def short_statement
|
27
|
-
"#{'unless ' if sexp[2].nil?}#{Ruby2Ruby.new.process(sexp[1].clone!)}"
|
28
|
-
end
|
29
|
-
|
30
|
-
def return_value
|
31
|
-
edit Ruby2Ruby.new.process(if_return_value.clone!)
|
32
|
-
end
|
33
|
-
|
34
|
-
def else_return_value
|
35
|
-
edit Ruby2Ruby.new.process(find_else_return_val.clone!)
|
36
|
-
end
|
37
|
-
|
38
|
-
def if_return_value
|
39
|
-
if sexp[2].nil?
|
40
|
-
sexp.last
|
41
|
-
elsif sexp[2].first == :if
|
42
|
-
nil
|
43
|
-
elsif sexp[2].first == :block
|
44
|
-
sexp[2].last
|
45
|
-
elsif sexp[2].first == :rescue
|
46
|
-
sexp[2][1].last
|
47
|
-
else
|
48
|
-
sexp[2]
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def find_else_return_val
|
53
|
-
if sexp.compact[3].nil?
|
54
|
-
nil
|
55
|
-
elsif sexp[3].first == :block
|
56
|
-
sexp[3].last
|
57
|
-
elsif sexp[3].first == :if
|
58
|
-
nil
|
59
|
-
else
|
60
|
-
sexp[3]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def edit(txt)
|
65
|
-
txt = txt.to_s
|
66
|
-
txt.sub! /^return\b/, 'returns'
|
67
|
-
txt.sub! /^returns\s*$/, 'returns nil'
|
68
|
-
if txt.include?(' = ')
|
69
|
-
txt = "assigns #{txt}"
|
70
|
-
elsif !txt.empty? and txt !~ /^return/
|
71
|
-
txt = "returns #{txt.strip}"
|
72
|
-
end
|
73
|
-
txt.strip
|
74
|
-
end
|
75
|
-
|
76
|
-
#
|
77
|
-
# Private
|
78
|
-
#
|
79
|
-
|
80
|
-
# @description handles elsif
|
81
|
-
def load_parts
|
82
|
-
condition_parts = Set.new
|
83
|
-
sexp.each_sexp do |s|
|
84
|
-
if s.first == :if
|
85
|
-
condition_parts << self.class.new(s)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
condition_parts.to_a
|
89
|
-
end
|
90
|
-
|
91
|
-
def create_nested_conditions
|
92
|
-
nc = Set.new
|
93
|
-
s = sexp.drop(1)
|
94
|
-
s.flatten.include?(:if) && s.deep_each do |exp|
|
95
|
-
DRG::Decorators::SexpDecorator.new(exp).each_sexp_condition do |node|
|
96
|
-
nc << self.class.new(node)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
nc.to_a
|
100
|
-
end
|
101
|
-
end
|
data/lib/drg/ruby/const.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require 'ruby_parser'
|
2
|
-
|
3
|
-
class DRG::Ruby::Const
|
4
|
-
CLASS_MOD_DEFS = { class: :class, module: :module }
|
5
|
-
CONSTANT_DEFS = { cdecl: :class }.merge CLASS_MOD_DEFS
|
6
|
-
|
7
|
-
attr_reader :sexp
|
8
|
-
|
9
|
-
# @param [Sexp] sexp
|
10
|
-
def initialize(sexp)
|
11
|
-
sexp = sexp[2] if sexp[0] == :block
|
12
|
-
@sexp = sexp
|
13
|
-
end
|
14
|
-
|
15
|
-
# s(:module, :Admin, s(:class, :Super, nil, s(:class, :UsersController, s(:colon3, :ApplicationController), s(:defn, :name, s(:args)
|
16
|
-
# s(:class, :Report, nil, s(:cdecl, :DEFAULT_TZ, s(:str, "UTC")), s(:defs, s(:self), :enqueue,
|
17
|
-
def name(sexp = @sexp, list = [])
|
18
|
-
sexp = Array(sexp)
|
19
|
-
if sexp[1].is_a?(Sexp) && sexp[1][0] == :colon2
|
20
|
-
parts = sexp[1].to_a.flatten
|
21
|
-
list.concat parts.drop(parts.size / 2)
|
22
|
-
elsif CONSTANT_DEFS.key?(sexp[0])
|
23
|
-
list << sexp[1].to_s
|
24
|
-
# recurse unless the second element is nil, which indicates it's the end of the class/module definition
|
25
|
-
if !sexp[2].nil? || (sexp[3].is_a?(Sexp) and CLASS_MOD_DEFS.key?(sexp[3].first))
|
26
|
-
name(sexp.compact[2], list)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
list.join('::')
|
30
|
-
end
|
31
|
-
|
32
|
-
def type(sexp = @sexp, val = nil)
|
33
|
-
sexp = Array(sexp)
|
34
|
-
if sexp[1].is_a?(Sexp) && sexp[1][0] == :colon2
|
35
|
-
val = sexp[0]
|
36
|
-
elsif CONSTANT_DEFS.key?(sexp[0])
|
37
|
-
val = type(sexp.compact[2], sexp[0])
|
38
|
-
end
|
39
|
-
CONSTANT_DEFS[val]
|
40
|
-
end
|
41
|
-
|
42
|
-
def initialization_args
|
43
|
-
funcs.find(-> { OpenStruct.new }) { |func| func.name == :initialize }.args.to_a
|
44
|
-
end
|
45
|
-
|
46
|
-
def func_by_name(name_as_symbol)
|
47
|
-
funcs.find { |x| x.name == name_as_symbol }
|
48
|
-
end
|
49
|
-
|
50
|
-
def funcs
|
51
|
-
@funcs ||= load_funcs.flatten
|
52
|
-
end
|
53
|
-
|
54
|
-
def class?
|
55
|
-
type == :class
|
56
|
-
end
|
57
|
-
|
58
|
-
def module?
|
59
|
-
type == :module
|
60
|
-
end
|
61
|
-
|
62
|
-
# @todo
|
63
|
-
def instance_vars
|
64
|
-
end
|
65
|
-
|
66
|
-
# @todo
|
67
|
-
def class_vars
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def load_funcs(sexp_list = sexp)
|
73
|
-
marked_private = false
|
74
|
-
sexp_list.map { |node|
|
75
|
-
next unless node.is_a?(Sexp)
|
76
|
-
case node.first
|
77
|
-
when :defn
|
78
|
-
DRG::Ruby::InstanceFunc.new(node, marked_private)
|
79
|
-
when :defs
|
80
|
-
DRG::Ruby::ClassFunc.new(node, marked_private)
|
81
|
-
when :call
|
82
|
-
marked_private ||= node[2] == :private
|
83
|
-
nil
|
84
|
-
when ->(name) { CONSTANT_DEFS.key?(name) }
|
85
|
-
# @note handle diz kind stuff:
|
86
|
-
# s(:class, :VerificationCode, nil, s(:defs, s(:self), :find, s(:args, :*)))
|
87
|
-
# and
|
88
|
-
# s(:module, :ConditionParsers, s(:class, :ReturnValue, ...))
|
89
|
-
# and
|
90
|
-
# s(:class, :NotificationPresenter, nil, s(:call, nil, :extend, s(:const, :Forwardable)), s(:call, nil, :attr_reader, ...))
|
91
|
-
load_funcs(node.compact.drop(2))
|
92
|
-
else
|
93
|
-
# @todo uncomment with logger at debug level
|
94
|
-
# puts "got #{__method__} with #{node.first} and don't know how to handle it"
|
95
|
-
# @note :const seems to indicate module inclusion/extension
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
}.compact
|
99
|
-
end
|
100
|
-
end
|
data/lib/drg/ruby/func.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
class DRG::Ruby::Func < Struct.new(:sexp, :_private)
|
2
|
-
alias private? _private
|
3
|
-
|
4
|
-
def conditions
|
5
|
-
DRG::Decorators::SexpDecorator.new(sexp).each_sexp_condition.map &DRG::Ruby::Condition.method(:new)
|
6
|
-
end
|
7
|
-
|
8
|
-
def assignments
|
9
|
-
nodes = find_assignments(sexp)
|
10
|
-
sexp.find_nodes(:rescue).each do |node|
|
11
|
-
node = node[1] if node[1].first == :block
|
12
|
-
nodes.concat find_assignments(node)
|
13
|
-
end
|
14
|
-
nodes.map &DRG::Ruby::Assignment.method(:new)
|
15
|
-
end
|
16
|
-
|
17
|
-
def find_assignments(s_expression)
|
18
|
-
s_expression.find_nodes(:op_asgn_or) + s_expression.find_nodes(:iasgn)
|
19
|
-
end
|
20
|
-
|
21
|
-
# @note we drop(1) to get rid of :args (which should be the first item in the sexp)
|
22
|
-
# @note called from subclasses
|
23
|
-
def map_args(_sexp = sexp, list = [])
|
24
|
-
val = _sexp.first
|
25
|
-
return list.drop(1) unless val
|
26
|
-
case val
|
27
|
-
when Symbol
|
28
|
-
map_args(_sexp.drop(1), list << val)
|
29
|
-
when Sexp
|
30
|
-
map_args(_sexp.drop(1), list << val[1])
|
31
|
-
else
|
32
|
-
nil
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/drg/ruby.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'ruby_parser'
|
2
|
-
require 'delegate'
|
3
|
-
|
4
|
-
module DRG
|
5
|
-
class Ruby
|
6
|
-
autoload :Const, 'drg/ruby/const'
|
7
|
-
autoload :Condition, 'drg/ruby/condition'
|
8
|
-
autoload :Func, 'drg/ruby/func'
|
9
|
-
autoload :ClassFunc, 'drg/ruby/class_func'
|
10
|
-
autoload :InstanceFunc, 'drg/ruby/instance_func'
|
11
|
-
autoload :Assignment, 'drg/ruby/assignment'
|
12
|
-
|
13
|
-
attr_reader :sexp, :const
|
14
|
-
|
15
|
-
# @param [Pathname, String] file
|
16
|
-
def initialize(file)
|
17
|
-
@sexp = RubyParser.new.parse File.read(file)
|
18
|
-
@const = DRG::Ruby::Const.new(sexp)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/drg/spec.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
class DRG::Spec < DelegateClass(DRG::Ruby::Const)
|
2
|
-
# = Class
|
3
|
-
# generate a rspec file based on existing code
|
4
|
-
|
5
|
-
def self.default_indent_size
|
6
|
-
2
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.generate(file)
|
10
|
-
spec = new(file)
|
11
|
-
return if spec.funcs.empty? # nothing to do
|
12
|
-
lines = [%Q(require "spec_helper"), %Q(), %Q(describe #{spec.const} do)]
|
13
|
-
if spec.class?
|
14
|
-
spec.initialization_args.each do |arg|
|
15
|
-
lines << %Q( let(:#{arg.to_s.sub(/^[&*]/, '')}) {})
|
16
|
-
end
|
17
|
-
lines << %Q()
|
18
|
-
lines << %Q( subject { described_class.new #{spec.initialization_args.join(', ')} })
|
19
|
-
elsif spec.module?
|
20
|
-
lines << %Q( subject { Class.new { include #{spec.const} }.new })
|
21
|
-
end
|
22
|
-
lines << %Q()
|
23
|
-
spec.funcs.reject(&:private?).each do |func|
|
24
|
-
lines << %Q( describe #{spec.quote("#{func.class? ? '.' : '#'}#{func.name}")} do)
|
25
|
-
func.assignments.each do |assignment|
|
26
|
-
lines << %Q( it #{spec.quote(assignment)} do) << %Q( end)
|
27
|
-
end
|
28
|
-
func.conditions.each do |condition|
|
29
|
-
lines.concat spec.collect_contexts(condition, ' ')
|
30
|
-
end
|
31
|
-
lines << %Q( end) << %Q()
|
32
|
-
end
|
33
|
-
lines << %Q(end) << %Q()
|
34
|
-
lines
|
35
|
-
end
|
36
|
-
|
37
|
-
attr_reader :ruby, :file
|
38
|
-
|
39
|
-
def initialize(file)
|
40
|
-
@file = file
|
41
|
-
@ruby = DRG::Ruby.new(file)
|
42
|
-
super @ruby.const
|
43
|
-
end
|
44
|
-
|
45
|
-
def const
|
46
|
-
@const ||= begin
|
47
|
-
require file
|
48
|
-
Kernel.const_get(ruby.const.name)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def collect_contexts(condition, indent = '', contexts = [])
|
53
|
-
new_indent = indent + (' ' * self.class.default_indent_size)
|
54
|
-
contexts << %Q(#{indent}context #{quote(tr(condition.short_statement))} do) << %Q(#{new_indent}before {})
|
55
|
-
if should_print? condition.return_value
|
56
|
-
contexts << %Q(#{new_indent}it #{quote(condition.return_value)} do) << %Q(#{new_indent}end)
|
57
|
-
end
|
58
|
-
if condition.nested_conditions.any?
|
59
|
-
condition.nested_conditions.each { |nc| collect_contexts(nc, new_indent, contexts) }
|
60
|
-
end
|
61
|
-
contexts << %Q(#{indent}end) << %Q() # /context
|
62
|
-
if condition.parts.empty?
|
63
|
-
contexts << %Q(#{indent}context #{quote(tr(negate(condition.short_statement)))} do) << %Q(#{new_indent}before {})
|
64
|
-
if should_print? condition.else_return_value
|
65
|
-
contexts << %Q(#{new_indent}it #{quote(condition.else_return_value)} do) << %Q(#{new_indent}end)
|
66
|
-
end
|
67
|
-
contexts << %Q(#{indent}end)
|
68
|
-
end
|
69
|
-
condition.parts.each do |condition_part|
|
70
|
-
contexts << %Q(#{indent}context #{quote(tr(condition_part.short_statement))} do) << %Q(#{new_indent}before {})
|
71
|
-
contexts << %Q(#{new_indent}it #{quote(condition_part.return_value)} do) << %Q(#{new_indent}end)
|
72
|
-
contexts << %Q(#{indent}end)
|
73
|
-
if should_print? condition_part.else_return_value
|
74
|
-
contexts << %Q(#{indent}context #{quote(tr(negate(condition_part.short_statement)))} do) << %Q(#{new_indent}before {})
|
75
|
-
contexts << %Q(#{new_indent}it #{quote(condition_part.else_return_value)} do) << %Q(#{new_indent}end)
|
76
|
-
contexts << %Q(#{indent}end)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
contexts
|
80
|
-
end
|
81
|
-
|
82
|
-
def quote(txt)
|
83
|
-
txt = txt.to_s
|
84
|
-
txt.strip!
|
85
|
-
if txt =~ /"/
|
86
|
-
"%Q[#{txt.gsub(/\#\{(.*?)\}/m, '\#{\1}')}]"
|
87
|
-
else
|
88
|
-
%Q("#{txt}")
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def negate(phrase)
|
93
|
-
if phrase[/^unless /]
|
94
|
-
phrase.sub /^unless /, 'if '
|
95
|
-
else
|
96
|
-
"not #{phrase}"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def tr(phrase)
|
101
|
-
phrase.sub! /^if /, 'when '
|
102
|
-
phrase.sub! /^not if /, 'unless '
|
103
|
-
phrase.sub! /^if not /, 'unless '
|
104
|
-
phrase.sub! /then$/, ''
|
105
|
-
if phrase !~ /^(when|unless|not)/
|
106
|
-
phrase = "when #{phrase}"
|
107
|
-
end
|
108
|
-
phrase
|
109
|
-
end
|
110
|
-
|
111
|
-
# @description reject multiline statements, which means we messed up somewhere else, so let's hide that
|
112
|
-
def should_print?(txt)
|
113
|
-
!txt.empty? and txt !~ /\n/
|
114
|
-
end
|
115
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
module DRG
|
4
|
-
module Tasks
|
5
|
-
class SpecRunner
|
6
|
-
include Log
|
7
|
-
|
8
|
-
attr_reader :file
|
9
|
-
|
10
|
-
# @param [Pathname] file
|
11
|
-
def initialize(file)
|
12
|
-
@file = Pathname.new(file)
|
13
|
-
end
|
14
|
-
|
15
|
-
def perform
|
16
|
-
fail ArgumentError, %Q(File or directory does not exist: "#{file}") if !File.exists?(file) && !File.exists?("#{file}.rb")
|
17
|
-
ruby_files.each do |ruby_file|
|
18
|
-
rspec_file = Pathname.new(spec_file(ruby_file))
|
19
|
-
spec_file_path = rspec_file.to_s[%r|/(spec/.+)|, 1]
|
20
|
-
next if rspec_file.exist?.tap { |result| log "- #{spec_file_path} - already exists", :gray if result }
|
21
|
-
spec = generate_spec(ruby_file)
|
22
|
-
next unless spec
|
23
|
-
log "+ #{spec_file_path}"
|
24
|
-
FileUtils.mkdir_p(rspec_file.parent)
|
25
|
-
File.open(rspec_file, 'wb') do |f|
|
26
|
-
f << spec.join("\n")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def generate_spec(ruby_file)
|
32
|
-
spec = DRG::Spec.generate Pathname.new(File.expand_path(ruby_file))
|
33
|
-
if spec
|
34
|
-
spec
|
35
|
-
else
|
36
|
-
log "- #{ruby_file} - no methods", :gray
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def ruby_files
|
42
|
-
if File.directory?(file)
|
43
|
-
Dir[File.join(file, '**', '*.rb')]
|
44
|
-
else
|
45
|
-
if file.extname.empty?
|
46
|
-
["#{file}.rb"]
|
47
|
-
else
|
48
|
-
[file]
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# @note subbing out /app/ is Rails specific
|
54
|
-
def spec_file(ruby_file)
|
55
|
-
File.join(spec_path, "#{specify(ruby_file)}").sub '/app/', '/'
|
56
|
-
end
|
57
|
-
|
58
|
-
def specify(file_name)
|
59
|
-
file_name.sub('.rb', '_spec.rb')
|
60
|
-
end
|
61
|
-
|
62
|
-
def spec_path
|
63
|
-
if File.directory?(File.expand_path('spec'))
|
64
|
-
File.expand_path('spec')
|
65
|
-
else
|
66
|
-
fail "Couldn't find spec directory"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|