tweezer 0.1.0 → 0.1.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.
- checksums.yaml +13 -5
- data/.gitignore +2 -0
- data/.rspec +1 -1
- data/.rubocop.yml +2 -0
- data/.travis.yml +9 -0
- data/Gemfile +0 -1
- data/README.md +1 -41
- data/Rakefile +3 -1
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/exe/tweezer +3 -1
- data/lib/tweezer.rb +20 -1
- data/lib/tweezer/ast_helper.rb +62 -0
- data/lib/tweezer/cli.rb +27 -0
- data/lib/tweezer/errors.rb +3 -0
- data/lib/tweezer/gem.rb +84 -0
- data/lib/tweezer/gemfile.rb +129 -0
- data/lib/tweezer/unparser/buffer.rb +7 -0
- data/lib/tweezer/unparser/emitter.rb +16 -0
- data/lib/tweezer/unparser/emitter/blank_line.rb +19 -0
- data/lib/tweezer/unparser/emitter/literal/primitive/inspect.rb +22 -0
- data/lib/tweezer/unparser/emitter/send/regular.rb +18 -0
- data/lib/tweezer/unparser/emitter/unparenthesized_arguments.rb +15 -0
- data/lib/tweezer/version.rb +1 -1
- data/tweezer.gemspec +9 -3
- metadata +122 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
N2MzN2NmNDM3NWRlMDVjNzg3YzRlODkzNTc2ODAyOWQzYzM0MDk1ZQ==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
ODUzNWE4YzRjMzcwZWFjZDJiODZhZjYwZGE4NmU3ODg5NTlkMzBlYQ==
|
|
5
7
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
YmYzZjQ2ZDhiMzI0NTFiN2NmZjhjMzZmZTAwOGU3NjViNTNkYzllY2M2YzIy
|
|
10
|
+
NmM4OTI5NTAzNjRiNzU5MmMzMDFiZjBiNTNiMDRjMTI2NTgzYzVjM2ZmNGNj
|
|
11
|
+
MmIwMzUzOGI4ZDUzYTNjMzQxZTU3ZGMxMTIxMDI5OTkzYWRkMDA=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
ZmIyZTE0MmJkNDQzNjA1MDhmYzMxNzFiNGI4YzU2NGQ0YTMxZDM3ZmIxNzlk
|
|
14
|
+
NTYyYjMzNjJjNjRjZGJiYTIzOWQ2ZGIyYjVmNzM5YWQwYWQ1MTBjOTMzN2Jm
|
|
15
|
+
OTJmNmMxOThmNmQ5ZjM4ZTc0YzczMTAwZDQ1ZDJiNmU1YjA1ZDc=
|
data/.rspec
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
--format
|
|
1
|
+
--format progress
|
|
2
2
|
--color
|
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
sudo: false
|
|
1
2
|
language: ruby
|
|
2
3
|
rvm:
|
|
3
4
|
- 2.2.2
|
|
4
5
|
before_install: gem install bundler -v 1.10.6
|
|
6
|
+
deploy:
|
|
7
|
+
provider: rubygems
|
|
8
|
+
api_key:
|
|
9
|
+
secure: zkccSICCWfIfzaJWRdb04cR4K7LcRdN96Bx/RKsdmKahza8o7Yu8eRL+yadW5w+Td9iujVcvtGBLcvyJg5NzXFv52ZJERhEW10MGIXYvbRNTwPjioP2PNYFp3xEwnQ4ELS6lITQKEt9odL7VrDkSUUcqVx9+EgMximQqPJCBRLJi6EtOPzvSrp794kt7LMwxJItDTnA7QyXk55iiR93irCB6iy64r0SKtFKsqmUnCsMCK+0Yky0or7Y/fU/+TRK2lkq2qKRt+iZf+EtEPOxoUQiICKFOPc31XR5ln6ZQF43Fvg0jLjfJ0p4DBwyhY9c1OBjK8PRzvKdTPjpq5MFgYWPk9C0xC5ZZI+BteQZowXe52tkTUKP1Px0c1Tx9bsoQW9N5dNlMuse19WlulK1G8kZ3gWWPKE5MGpMQgVGQq8CKSkUmwwBeLGvS5+yFCNOU52X8zVp9PRs4g3cdoauSdXMi+fewCRnIsp+ONJJw3V3IQVRIDoGv81ZO/TECsmDiVOv7AqzR1eG2Mc9PRrFCa7wUOfKG8fL23ZsYMLVct3VtN8TOYwEKtYY+vNM25Rsbxvbx1Q7qN5oywySS5jaKBrYkUmbfqEW6UOCqA/Nu+41OwehfgN74NkiOWDoIhVjHLrJlbuQR0Vzg9zw6s00lIQnY+MyZplsDQ4XvVZy2DDA=
|
|
10
|
+
gem: tweezer
|
|
11
|
+
on:
|
|
12
|
+
tags: true
|
|
13
|
+
repo: glittershark/tweezer
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,41 +1 @@
|
|
|
1
|
-
# Tweezer
|
|
2
|
-
|
|
3
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/tweezer`. To experiment with that code, run `bin/console` for an interactive prompt.
|
|
4
|
-
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
8
|
-
|
|
9
|
-
Add this line to your application's Gemfile:
|
|
10
|
-
|
|
11
|
-
```ruby
|
|
12
|
-
gem 'tweezer'
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
And then execute:
|
|
16
|
-
|
|
17
|
-
$ bundle
|
|
18
|
-
|
|
19
|
-
Or install it yourself as:
|
|
20
|
-
|
|
21
|
-
$ gem install tweezer
|
|
22
|
-
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
TODO: Write usage instructions here
|
|
26
|
-
|
|
27
|
-
## Development
|
|
28
|
-
|
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec tweezer` to use the gem in this directory, ignoring other installed copies of this gem.
|
|
30
|
-
|
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
32
|
-
|
|
33
|
-
## Contributing
|
|
34
|
-
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/tweezer.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## License
|
|
39
|
-
|
|
40
|
-
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
41
|
-
|
|
1
|
+
# Tweezer [](https://travis-ci.org/glittershark/tweezer)
|
data/Rakefile
CHANGED
data/bin/rake
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# This file was generated by Bundler.
|
|
4
|
+
#
|
|
5
|
+
# The application 'rake' is installed as part of a gem, and
|
|
6
|
+
# this file is here to facilitate running it.
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
require 'pathname'
|
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
|
11
|
+
Pathname.new(__FILE__).realpath)
|
|
12
|
+
|
|
13
|
+
require 'rubygems'
|
|
14
|
+
require 'bundler/setup'
|
|
15
|
+
|
|
16
|
+
load Gem.bin_path('rake', 'rake')
|
data/bin/rspec
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# This file was generated by Bundler.
|
|
4
|
+
#
|
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
|
6
|
+
# this file is here to facilitate running it.
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
require 'pathname'
|
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
|
11
|
+
Pathname.new(__FILE__).realpath)
|
|
12
|
+
|
|
13
|
+
require 'rubygems'
|
|
14
|
+
require 'bundler/setup'
|
|
15
|
+
|
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/exe/tweezer
CHANGED
data/lib/tweezer.rb
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'set'
|
|
2
2
|
|
|
3
3
|
module Tweezer
|
|
4
|
+
UNPARENTHESIZED_METHODS = Set[*%i(source ruby git path group platforms gem)]
|
|
5
|
+
|
|
6
|
+
def self.unparenthesized_method?(method)
|
|
7
|
+
UNPARENTHESIZED_METHODS.include?(method)
|
|
8
|
+
end
|
|
4
9
|
end
|
|
10
|
+
|
|
11
|
+
require 'unparser'
|
|
12
|
+
require 'tweezer/unparser/buffer'
|
|
13
|
+
require 'tweezer/unparser/emitter'
|
|
14
|
+
require 'tweezer/unparser/emitter/literal/primitive/inspect'
|
|
15
|
+
require 'tweezer/unparser/emitter/send/regular'
|
|
16
|
+
require 'tweezer/unparser/emitter/unparenthesized_arguments'
|
|
17
|
+
require 'tweezer/unparser/emitter/blank_line'
|
|
18
|
+
require 'tweezer/version'
|
|
19
|
+
require 'tweezer/errors'
|
|
20
|
+
require 'tweezer/ast_helper'
|
|
21
|
+
require 'tweezer/gem'
|
|
22
|
+
require 'tweezer/gemfile'
|
|
23
|
+
require 'tweezer/cli'
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Tweezer
|
|
2
|
+
module ASTHelper
|
|
3
|
+
def s(type, *children)
|
|
4
|
+
Parser::AST::Node.new(type, children)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def blank_line
|
|
8
|
+
Parser::AST::Node.new(:blank_line)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def block?(node)
|
|
12
|
+
node.type == :block
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def source_block?(node)
|
|
16
|
+
block?(node) &&
|
|
17
|
+
node.children[0].type == :send &&
|
|
18
|
+
node.children[0].children[1] == :source
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def group_block?(node)
|
|
22
|
+
block?(node) &&
|
|
23
|
+
node.children[0].type == :send &&
|
|
24
|
+
node.children[0].children[1] == :group
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def block_children(node)
|
|
28
|
+
child = node.children[2]
|
|
29
|
+
children = child.type == :begin ? child.children : [child]
|
|
30
|
+
return children unless block_given?
|
|
31
|
+
children.each { |c| yield c }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def groups_from_group_block(node)
|
|
35
|
+
node.children[0].children[2..-1].flat_map(&:children)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def unparse_hash_node(node)
|
|
39
|
+
fail ArgumentError unless node.type == :hash
|
|
40
|
+
node.children.map do |child|
|
|
41
|
+
[child.children[0].children[0], child.children[1]]
|
|
42
|
+
end.to_h
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def append_block_child(block, node)
|
|
46
|
+
new_children = block.children[0..1]
|
|
47
|
+
old_child = block.children[2]
|
|
48
|
+
|
|
49
|
+
if old_child.type == :begin
|
|
50
|
+
new_children << old_child.append(node)
|
|
51
|
+
else
|
|
52
|
+
new_children << s(:begin, old_child, node)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
block.updated(nil, new_children)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
module_function :s, :block?, :source_block?, :group_block?, :block_children,
|
|
59
|
+
:groups_from_group_block, :unparse_hash_node,
|
|
60
|
+
:append_block_child
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/tweezer/cli.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'bundler'
|
|
3
|
+
|
|
4
|
+
module Tweezer
|
|
5
|
+
class CLI < Thor
|
|
6
|
+
def initialize(*)
|
|
7
|
+
super
|
|
8
|
+
|
|
9
|
+
custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile]
|
|
10
|
+
if custom_gemfile && !custom_gemfile.empty?
|
|
11
|
+
ENV['BUNDLE_GEMFILE'] = File.expand_path(custom_gemfile)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@gemfile = Tweezer::Gemfile.load
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc 'add GEM [VERSION]',
|
|
18
|
+
'add GEM to the gemfile, optionally pinned to VERSION'
|
|
19
|
+
option :groups, type: :array, aliases: '-g',
|
|
20
|
+
desc: 'Groups to add the gem to'
|
|
21
|
+
def add(name, version = nil)
|
|
22
|
+
groups = options[:groups].map(&:to_sym) if options[:groups]
|
|
23
|
+
@gemfile.add_gem(name, version, groups: groups || [])
|
|
24
|
+
@gemfile.save!
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/tweezer/gem.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Tweezer
|
|
2
|
+
class Gem
|
|
3
|
+
include Tweezer::ASTHelper
|
|
4
|
+
|
|
5
|
+
def initialize(node_or_name, version = nil, opts = {})
|
|
6
|
+
return init_from_node(node_or_name) if node_or_name.is_a?(
|
|
7
|
+
Parser::AST::Node)
|
|
8
|
+
|
|
9
|
+
@name = node_or_name
|
|
10
|
+
|
|
11
|
+
if version.is_a? Hash
|
|
12
|
+
@version = nil
|
|
13
|
+
opts = version
|
|
14
|
+
else
|
|
15
|
+
@version = version
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
@groups = opts[:groups]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_node
|
|
22
|
+
args = [nil, :gem, s(:str, name)]
|
|
23
|
+
args << s(:str, version) if version
|
|
24
|
+
args << s(:hash, groups_to_node) unless groups.empty?
|
|
25
|
+
|
|
26
|
+
Parser::AST::Node.new(:send, args)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def ==(other)
|
|
30
|
+
name == other.name &&
|
|
31
|
+
version == other.version
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.gem_node?(node)
|
|
35
|
+
node.children[1] == :gem
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
attr_reader :name, :version
|
|
39
|
+
attr_writer :groups
|
|
40
|
+
|
|
41
|
+
def groups
|
|
42
|
+
@groups ||= []
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# rubocop:disable Metrics/AbcSize
|
|
48
|
+
def init_from_node(node)
|
|
49
|
+
check_node!(node)
|
|
50
|
+
arguments = node.children[2..-1]
|
|
51
|
+
opts = arguments.pop if arguments[-1].type == :hash
|
|
52
|
+
|
|
53
|
+
@name = arguments[0].children[0]
|
|
54
|
+
@version = arguments[1].children[0] if arguments[1]
|
|
55
|
+
|
|
56
|
+
return unless opts
|
|
57
|
+
@groups = groups_from_node(unparse_hash_node(opts)[:group])
|
|
58
|
+
end
|
|
59
|
+
# rubocop:enable Metrics/AbcSize
|
|
60
|
+
|
|
61
|
+
def groups_to_node
|
|
62
|
+
s(:pair,
|
|
63
|
+
s(:sym, :group),
|
|
64
|
+
if groups.length == 1
|
|
65
|
+
s(:sym, groups[0])
|
|
66
|
+
else
|
|
67
|
+
s(:array, groups.map { |g| s(:sym, g) })
|
|
68
|
+
end)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def groups_from_node(node)
|
|
72
|
+
case node.type
|
|
73
|
+
when :sym then [node.children[0]]
|
|
74
|
+
when :array then node.children.flat_map(&:children)
|
|
75
|
+
else fail ArgumentError
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def check_node!(node)
|
|
80
|
+
return if self.class.gem_node?(node)
|
|
81
|
+
fail ArgumentError, "Not a call to `gem`: #{node.inspect}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
require 'parser/current'
|
|
3
|
+
require 'unparser'
|
|
4
|
+
|
|
5
|
+
module Tweezer
|
|
6
|
+
class Gemfile
|
|
7
|
+
include Tweezer::ASTHelper
|
|
8
|
+
|
|
9
|
+
def initialize(source, file = nil)
|
|
10
|
+
@ast, @comments = Parser::CurrentRuby.parse_with_comments(source, file)
|
|
11
|
+
@file = file
|
|
12
|
+
|
|
13
|
+
load_nodes!(@ast.children)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.load(file = Bundler.default_gemfile)
|
|
17
|
+
new(File.read(file), file)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def save!
|
|
21
|
+
fail unless @file
|
|
22
|
+
File.write(@file, dump)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def gems
|
|
26
|
+
@gems ||= []
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Maps arrays of groups to arrays of Gems
|
|
30
|
+
def groups
|
|
31
|
+
@groups ||= Hash.new { |h, k| h[k] = [] }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# rubocop:disable Metrics/AbcSize
|
|
35
|
+
# rubocop:disable Metrics/MethodLength
|
|
36
|
+
def add_gem(*args)
|
|
37
|
+
gem = Gem.new(*args)
|
|
38
|
+
fail GemAlreadyPresent if gems.include? gem
|
|
39
|
+
gems << gem
|
|
40
|
+
|
|
41
|
+
if groups.include?(gem.groups)
|
|
42
|
+
gem_groups = gem.groups
|
|
43
|
+
gem.groups = []
|
|
44
|
+
|
|
45
|
+
if groups[gem_groups].size == 1
|
|
46
|
+
gem_to_group_block!(groups[gem_groups].first)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
append_to_group_block! gem.to_node, groups: gem_groups
|
|
50
|
+
else
|
|
51
|
+
groups[gem.groups] = [gem] unless gem.groups.empty?
|
|
52
|
+
append_before_first_block! gem.to_node
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
# rubocop:enable Metrics/MethodLength
|
|
56
|
+
# rubocop:enable Metrics/AbcSize
|
|
57
|
+
|
|
58
|
+
def dump
|
|
59
|
+
Unparser.unparse(ast, comments)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
attr_reader :ast, :comments
|
|
65
|
+
|
|
66
|
+
def load_nodes!(nodes)
|
|
67
|
+
nodes.map { |node| load_node! node }.compact
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def load_node!(node)
|
|
71
|
+
return load_block_node!(node) if block? node
|
|
72
|
+
return unless Gem.gem_node?(node)
|
|
73
|
+
|
|
74
|
+
gem = Gem.new(node)
|
|
75
|
+
gems << gem
|
|
76
|
+
groups[gem.groups] << gem unless gem.groups.empty?
|
|
77
|
+
gem
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def load_block_node!(node)
|
|
81
|
+
fail ArgumentError unless block?(node)
|
|
82
|
+
gems = load_nodes!(block_children(node))
|
|
83
|
+
groups[groups_from_group_block(node)].concat(gems) if group_block?(node)
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def append_before_first_block!(new_node)
|
|
88
|
+
nodes = ast.children.flat_map do |node|
|
|
89
|
+
block?(node) ? [new_node, blank_line, node] : [node]
|
|
90
|
+
end
|
|
91
|
+
nodes << new_node unless nodes.include? new_node
|
|
92
|
+
|
|
93
|
+
@ast = @ast.updated(nil, nodes)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def append_to_group_block!(new_node, groups: [])
|
|
97
|
+
nodes = ast.children.map do |node|
|
|
98
|
+
if group_block?(node) && groups_from_group_block(node) == groups
|
|
99
|
+
append_block_child(node, new_node)
|
|
100
|
+
else
|
|
101
|
+
node
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
@ast = @ast.updated(nil, nodes)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def gem_to_group_block!(gem)
|
|
109
|
+
nodes = ast.children.flat_map do |node|
|
|
110
|
+
next [node] unless node == gem.to_node
|
|
111
|
+
|
|
112
|
+
gem_groups = gem.groups
|
|
113
|
+
gem.groups = []
|
|
114
|
+
|
|
115
|
+
[blank_line, group_block(gem_groups, gem), blank_line]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
@ast = @ast.updated(nil, nodes)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def group_block(groups, *gems)
|
|
122
|
+
s(:block,
|
|
123
|
+
s(:send, nil, :group,
|
|
124
|
+
*(groups.map { |group| s(:sym, group) })),
|
|
125
|
+
s(:args),
|
|
126
|
+
*gems.map(&:to_node))
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Unparser
|
|
2
|
+
class Emitter
|
|
3
|
+
def write_to_buffer
|
|
4
|
+
emit_comments_before if buffer.fresh_line?
|
|
5
|
+
fix_newlines
|
|
6
|
+
dispatch
|
|
7
|
+
comments.consume(node)
|
|
8
|
+
emit_eof_comments if parent.is_a?(Root)
|
|
9
|
+
self
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def fix_newlines
|
|
13
|
+
(node.loc.line - buffer.current_line).times { buffer.nl } if node.loc
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'unparser'
|
|
2
|
+
|
|
3
|
+
module Unparser
|
|
4
|
+
class Emitter
|
|
5
|
+
old = REGISTRY.dup
|
|
6
|
+
remove_const :REGISTRY
|
|
7
|
+
const_set :REGISTRY, old.dup
|
|
8
|
+
|
|
9
|
+
class BlankLine < self
|
|
10
|
+
handle :blank_line
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def dispatch; end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
REGISTRY.freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Unparser
|
|
2
|
+
class Emitter
|
|
3
|
+
class Literal
|
|
4
|
+
class Primitive < self
|
|
5
|
+
class Inspect < self
|
|
6
|
+
def dispatch
|
|
7
|
+
return write_inspect unless value.is_a? String
|
|
8
|
+
return write_inspect if value.include? "'"
|
|
9
|
+
|
|
10
|
+
write("'#{value}'")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def write_inspect
|
|
16
|
+
write(value.inspect)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Unparser
|
|
2
|
+
class Emitter
|
|
3
|
+
class Send
|
|
4
|
+
class Regular < self
|
|
5
|
+
def emit_arguments
|
|
6
|
+
case
|
|
7
|
+
when arguments.empty? && receiver.nil? && local_variable_clash?
|
|
8
|
+
write('()')
|
|
9
|
+
when Tweezer.unparenthesized_method?(selector)
|
|
10
|
+
run(UnparenthesizedArguments, n(:arguments, arguments))
|
|
11
|
+
else
|
|
12
|
+
run(Arguments, n(:arguments, arguments))
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'unparser'
|
|
2
|
+
|
|
3
|
+
module Unparser
|
|
4
|
+
class Emitter
|
|
5
|
+
class UnparenthesizedArguments < Unparser::Emitter::Send::Arguments
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def dispatch
|
|
9
|
+
return if children.empty?
|
|
10
|
+
write(' ')
|
|
11
|
+
delimited_plain(effective_arguments)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/tweezer/version.rb
CHANGED
data/tweezer.gemspec
CHANGED
|
@@ -27,9 +27,15 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
spec.require_paths = ['lib']
|
|
28
28
|
|
|
29
29
|
spec.add_dependency 'parser', '~> 2.2'
|
|
30
|
+
spec.add_dependency 'thor', '~> 0.19'
|
|
31
|
+
spec.add_dependency 'unparser', '~> 0.2'
|
|
32
|
+
spec.add_dependency 'bundler', '~> 1.10'
|
|
33
|
+
spec.add_dependency 'activesupport', '~> 4.2'
|
|
30
34
|
|
|
31
|
-
spec.add_development_dependency 'bundler', '~> 1.10'
|
|
32
35
|
spec.add_development_dependency 'rake', '~> 10.0'
|
|
33
|
-
spec.add_development_dependency 'rspec'
|
|
34
|
-
spec.add_development_dependency '
|
|
36
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
|
37
|
+
spec.add_development_dependency 'rspec-its', '~> 1.2'
|
|
38
|
+
spec.add_development_dependency 'rspec-collection_matchers', '~> 1.1'
|
|
39
|
+
spec.add_development_dependency 'rubocop', '~> 0.34'
|
|
40
|
+
spec.add_development_dependency 'pry', '~> 0.10'
|
|
35
41
|
end
|
metadata
CHANGED
|
@@ -1,88 +1,171 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tweezer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Griffin Smith
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-10-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: parser
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - ~>
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '2.2'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - ~>
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '2.2'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: thor
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ~>
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.19'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ~>
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.19'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: unparser
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ~>
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.2'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ~>
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.2'
|
|
27
55
|
- !ruby/object:Gem::Dependency
|
|
28
56
|
name: bundler
|
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
|
30
58
|
requirements:
|
|
31
|
-
- -
|
|
59
|
+
- - ~>
|
|
32
60
|
- !ruby/object:Gem::Version
|
|
33
61
|
version: '1.10'
|
|
34
|
-
type: :
|
|
62
|
+
type: :runtime
|
|
35
63
|
prerelease: false
|
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
65
|
requirements:
|
|
38
|
-
- -
|
|
66
|
+
- - ~>
|
|
39
67
|
- !ruby/object:Gem::Version
|
|
40
68
|
version: '1.10'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: activesupport
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ~>
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '4.2'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ~>
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '4.2'
|
|
41
83
|
- !ruby/object:Gem::Dependency
|
|
42
84
|
name: rake
|
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
|
44
86
|
requirements:
|
|
45
|
-
- -
|
|
87
|
+
- - ~>
|
|
46
88
|
- !ruby/object:Gem::Version
|
|
47
89
|
version: '10.0'
|
|
48
90
|
type: :development
|
|
49
91
|
prerelease: false
|
|
50
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
93
|
requirements:
|
|
52
|
-
- -
|
|
94
|
+
- - ~>
|
|
53
95
|
- !ruby/object:Gem::Version
|
|
54
96
|
version: '10.0'
|
|
55
97
|
- !ruby/object:Gem::Dependency
|
|
56
98
|
name: rspec
|
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
|
58
100
|
requirements:
|
|
59
|
-
- -
|
|
101
|
+
- - ~>
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '3.3'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ~>
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '3.3'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rspec-its
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ~>
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '1.2'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ~>
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '1.2'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rspec-collection_matchers
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ~>
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '1.1'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ~>
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '1.1'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: rubocop
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ~>
|
|
60
144
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
145
|
+
version: '0.34'
|
|
62
146
|
type: :development
|
|
63
147
|
prerelease: false
|
|
64
148
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
149
|
requirements:
|
|
66
|
-
- -
|
|
150
|
+
- - ~>
|
|
67
151
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
152
|
+
version: '0.34'
|
|
69
153
|
- !ruby/object:Gem::Dependency
|
|
70
154
|
name: pry
|
|
71
155
|
requirement: !ruby/object:Gem::Requirement
|
|
72
156
|
requirements:
|
|
73
|
-
- -
|
|
157
|
+
- - ~>
|
|
74
158
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
159
|
+
version: '0.10'
|
|
76
160
|
type: :development
|
|
77
161
|
prerelease: false
|
|
78
162
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
163
|
requirements:
|
|
80
|
-
- -
|
|
164
|
+
- - ~>
|
|
81
165
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
|
-
description:
|
|
84
|
-
|
|
85
|
-
automated way
|
|
166
|
+
version: '0.10'
|
|
167
|
+
description: ! " Tweezer is a CLI to add, remove, and edit Gemfile dependencies
|
|
168
|
+
in an\n automated way\n"
|
|
86
169
|
email:
|
|
87
170
|
- wildgriffin45@gmail.com
|
|
88
171
|
executables:
|
|
@@ -90,17 +173,31 @@ executables:
|
|
|
90
173
|
extensions: []
|
|
91
174
|
extra_rdoc_files: []
|
|
92
175
|
files:
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
176
|
+
- .gitignore
|
|
177
|
+
- .rspec
|
|
178
|
+
- .rubocop.yml
|
|
179
|
+
- .travis.yml
|
|
96
180
|
- Gemfile
|
|
97
181
|
- LICENSE.txt
|
|
98
182
|
- README.md
|
|
99
183
|
- Rakefile
|
|
100
184
|
- bin/console
|
|
185
|
+
- bin/rake
|
|
186
|
+
- bin/rspec
|
|
101
187
|
- bin/setup
|
|
102
188
|
- exe/tweezer
|
|
103
189
|
- lib/tweezer.rb
|
|
190
|
+
- lib/tweezer/ast_helper.rb
|
|
191
|
+
- lib/tweezer/cli.rb
|
|
192
|
+
- lib/tweezer/errors.rb
|
|
193
|
+
- lib/tweezer/gem.rb
|
|
194
|
+
- lib/tweezer/gemfile.rb
|
|
195
|
+
- lib/tweezer/unparser/buffer.rb
|
|
196
|
+
- lib/tweezer/unparser/emitter.rb
|
|
197
|
+
- lib/tweezer/unparser/emitter/blank_line.rb
|
|
198
|
+
- lib/tweezer/unparser/emitter/literal/primitive/inspect.rb
|
|
199
|
+
- lib/tweezer/unparser/emitter/send/regular.rb
|
|
200
|
+
- lib/tweezer/unparser/emitter/unparenthesized_arguments.rb
|
|
104
201
|
- lib/tweezer/version.rb
|
|
105
202
|
- tweezer.gemspec
|
|
106
203
|
homepage: https://github.com/glittershark/tweezer
|
|
@@ -113,12 +210,12 @@ require_paths:
|
|
|
113
210
|
- lib
|
|
114
211
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
115
212
|
requirements:
|
|
116
|
-
- -
|
|
213
|
+
- - ! '>='
|
|
117
214
|
- !ruby/object:Gem::Version
|
|
118
215
|
version: '0'
|
|
119
216
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
217
|
requirements:
|
|
121
|
-
- -
|
|
218
|
+
- - ! '>='
|
|
122
219
|
- !ruby/object:Gem::Version
|
|
123
220
|
version: '0'
|
|
124
221
|
requirements: []
|