gemfile_arranger 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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.hound.yml +3 -0
- data/.rubocop-todo.yml +9 -0
- data/.rubocop.yml +12 -0
- data/.tachikoma.yml +1 -0
- data/.travis.yml +13 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +37 -0
- data/Rakefile +8 -0
- data/bin/gemfile_arrange +6 -0
- data/config/.gemfile_arranger.base.yml +12 -0
- data/example.txt +41 -0
- data/examples/idobata.io.Gemfile +100 -0
- data/examples/pigeon.tachikoma.io.Gemfile +86 -0
- data/examples/sort-example.Gemfile +18 -0
- data/gemfile_arranger.gemspec +29 -0
- data/lib/gemfile_arranger.rb +7 -0
- data/lib/gemfile_arranger/cli.rb +126 -0
- data/lib/gemfile_arranger/templates/.gemfile_arranger.yml +15 -0
- data/lib/gemfile_arranger/testing.rb +13 -0
- data/lib/gemfile_arranger/traverse/sort_block.rb +22 -0
- data/lib/gemfile_arranger/traverse/sort_gems_in_group.rb +25 -0
- data/lib/gemfile_arranger/traverse/sort_priority_gems_in_group.rb +29 -0
- data/lib/gemfile_arranger/version.rb +3 -0
- data/test/helper.rb +4 -0
- data/test/test_testing.rb +29 -0
- data/test/test_traverse_sort_block.rb +72 -0
- data/test/test_traverse_sort_gems_in_group.rb +60 -0
- data/test/test_traverse_sort_priority_gems_in_group.rb +39 -0
- metadata +192 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 43ebe801a6d26a0a473e3ac5dacdfa6a6e85557c
|
4
|
+
data.tar.gz: 94696ef5d4040db27c90457aaf44b2fcb986637e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1de3a0dd30b33be2f3fb8e3d9e4670c20147cd2fb780ff1ed7d26515ccaf43475b02c82185bb402a9db32715e1dc0a81970e845c9f4160589a5ef68156ba8d13
|
7
|
+
data.tar.gz: 2a39f863a6abc96126f90413ffb74c41e8321636067ce4341527bf38fa793061dc0f6e4115afbbb8374360fd5d53518cbdc3b18dfb0f24d35cce5b550469532c
|
data/.gitignore
ADDED
data/.hound.yml
ADDED
data/.rubocop-todo.yml
ADDED
data/.rubocop.yml
ADDED
data/.tachikoma.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
strategy: 'none'
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 sanemat
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# GemfileArranger
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/gemfile_arranger)
|
4
|
+
[](https://travis-ci.org/sanemat/gemfile_arranger)
|
5
|
+
[](https://codeclimate.com/github/sanemat/gemfile_arranger)
|
6
|
+
[](https://coveralls.io/r/sanemat/gemfile_arranger)
|
7
|
+
|
8
|
+
|
9
|
+
TODO: Write a gem description
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'gemfile_arranger'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install gemfile_arranger
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
TODO: Write usage instructions here
|
30
|
+
|
31
|
+
## Contributing
|
32
|
+
|
33
|
+
1. Fork it ( https://github.com/sanemat/gemfile_arranger/fork )
|
34
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
35
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
36
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
37
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/gemfile_arrange
ADDED
data/example.txt
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
yaml setting(idea: .gemfile_arranger.yml)
|
2
|
+
|
3
|
+
block_order:
|
4
|
+
- source
|
5
|
+
- ruby
|
6
|
+
- gemspec
|
7
|
+
- gem
|
8
|
+
- group
|
9
|
+
group:
|
10
|
+
- production
|
11
|
+
- staging
|
12
|
+
- development
|
13
|
+
- test
|
14
|
+
priority_gem:
|
15
|
+
- rails
|
16
|
+
- redis
|
17
|
+
|
18
|
+
idobata rule:
|
19
|
+
https://gist.github.com/kakutani/43b9f42197ab002fcdf8
|
20
|
+
|
21
|
+
examples:
|
22
|
+
- examples/idobata.io.Gemfile
|
23
|
+
- examples/pigeon.tachikoma.io.Gemfile
|
24
|
+
|
25
|
+
## 説明
|
26
|
+
|
27
|
+
1. どのブロックなのかがわかる
|
28
|
+
2. ブロックごとに並べる
|
29
|
+
3. ブロックの中で、
|
30
|
+
|
31
|
+
- [x] sourceを一番上のグループ、rubyを二番目のグループ, gemspecを三番目, gemを四番目, groupを五番目に並べる
|
32
|
+
- groupの並び順設定通りに並べる
|
33
|
+
- groupの並び順設定がなければ、sortの設定で、groupを並べる
|
34
|
+
- [x] priority_gem設定があり、各group内でpriority_gemがあったら、まずその順番に並べる
|
35
|
+
- 3番目のグループから、sortの設定で、gemを並べ替える
|
36
|
+
|
37
|
+
## 懸念
|
38
|
+
|
39
|
+
- 裸のgemにgroupがついていたら?? -> { group: :development } がつくだけなので注意
|
40
|
+
- Bundler::Dsl にpublicで定義されたメソッドしか使えない ホワイトリストで良さそう(ただし動的に作る)
|
41
|
+
- dog-fooding
|
@@ -0,0 +1,100 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
ruby '2.1.2'
|
4
|
+
|
5
|
+
gem 'action_args'
|
6
|
+
gem 'actionpack-xml_parser'
|
7
|
+
gem 'actionview-encoded_mail_to'
|
8
|
+
gem 'active_attr'
|
9
|
+
gem 'active_model_serializers', github: 'ursm/active_model_serializers', branch: 'rails-4.1'
|
10
|
+
gem 'bootstrap-sass', '~> 2.3' # TODO 3.x に上げる
|
11
|
+
gem 'carrierwave'
|
12
|
+
gem 'carrierwave_backgrounder'
|
13
|
+
gem 'cells'
|
14
|
+
gem 'chronic'
|
15
|
+
gem 'closure-compiler'
|
16
|
+
gem 'coffee-rails', '~> 4.0.0'
|
17
|
+
gem 'custom_configuration'
|
18
|
+
gem 'devise'
|
19
|
+
gem 'devise-async'
|
20
|
+
gem 'ember-data-source', '0.14'
|
21
|
+
gem 'ember-rails'
|
22
|
+
gem 'enumerize', github: 'ursm/enumerize', branch: 'fix-ar4'
|
23
|
+
gem 'escape_utils'
|
24
|
+
gem 'event_tracker'
|
25
|
+
gem 'figaro'
|
26
|
+
gem 'fog'
|
27
|
+
gem 'font-awesome-rails'
|
28
|
+
gem 'gcm'
|
29
|
+
gem 'gemoji'
|
30
|
+
gem 'girl_friday'
|
31
|
+
gem 'github-linguist', group: 'has-icu'
|
32
|
+
gem 'github-markdown'
|
33
|
+
gem 'grocer'
|
34
|
+
gem 'haml-rails'
|
35
|
+
gem 'hamlbars'
|
36
|
+
gem 'hashie'
|
37
|
+
gem 'hiredis'
|
38
|
+
gem 'hpricot'
|
39
|
+
gem 'html-pipeline', require: 'html/pipeline', github: 'jch/html-pipeline'
|
40
|
+
gem 'jquery-atwho-rails', '0.4.7' # 0.4.9 は補完が妙高さんになる
|
41
|
+
gem 'jquery-rails'
|
42
|
+
gem 'jquery-ui-rails'
|
43
|
+
gem 'mini_magick'
|
44
|
+
gem 'momentjs-rails'
|
45
|
+
gem 'oj'
|
46
|
+
gem 'omniauth'
|
47
|
+
gem 'omniauth-github'
|
48
|
+
gem 'party_foul', github: 'tricknotes/party_foul', branch: 'fix-issue-labels-format' # Workaround until this PR is merged: https://github.com/dockyard/party_foul/pull/103
|
49
|
+
gem 'pg'
|
50
|
+
gem 'pusher'
|
51
|
+
gem 'rails', '~> 4.1.0'
|
52
|
+
gem 'redcarpet'
|
53
|
+
gem 'redis', require: %w(redis redis/connection/hiredis)
|
54
|
+
gem 'redis-objects', require: 'redis/objects'
|
55
|
+
gem 'retriable'
|
56
|
+
gem 'rinku'
|
57
|
+
gem 'sanitize'
|
58
|
+
gem 'sass-rails', '~> 4.0.0'
|
59
|
+
gem 'sidekiq'
|
60
|
+
gem 'sinatra', require: false # Sidekiq::Web, GirlFriday::Server
|
61
|
+
gem 'skylight'
|
62
|
+
gem 'uglifier', '>= 1.3.0'
|
63
|
+
gem 'underscore-rails'
|
64
|
+
gem 'unf'
|
65
|
+
gem 'unicorn'
|
66
|
+
gem 'visibilityjs'
|
67
|
+
|
68
|
+
group :development do
|
69
|
+
gem 'bullet'
|
70
|
+
gem 'letter_opener'
|
71
|
+
gem 'pry', group: 'test'
|
72
|
+
gem 'quiet_assets'
|
73
|
+
gem 'tapp-awesome_print', group: 'test'
|
74
|
+
gem 'vendorer'
|
75
|
+
gem 'what_methods'
|
76
|
+
end
|
77
|
+
|
78
|
+
group :test do
|
79
|
+
gem 'capybara', github: 'jnicklas/capybara'
|
80
|
+
gem 'capybara-webkit'
|
81
|
+
gem 'database_rewinder'
|
82
|
+
gem 'email_spec', github: 'bmabey/email-spec'
|
83
|
+
gem 'factory_girl_rails', group: 'development'
|
84
|
+
gem 'fakeredis', require: 'fakeredis/rspec', github: 'guilleiguaran/fakeredis'
|
85
|
+
gem 'fuubar', '~> 2.0.0.beta'
|
86
|
+
gem 'launchy'
|
87
|
+
gem 'rspec-cells'
|
88
|
+
gem 'rspec-its'
|
89
|
+
gem 'rspec-rails', '~> 3.0.0.beta', group: 'development'
|
90
|
+
gem 'rspec-retry' # TravisCI上でどうしてもタイミング依存でfailするcapybara経由のexampleがあるので止むなし
|
91
|
+
gem 'teaspoon', group: 'development'
|
92
|
+
end
|
93
|
+
|
94
|
+
group :production do
|
95
|
+
gem 'dalli'
|
96
|
+
gem 'newrelic-redis'
|
97
|
+
gem 'newrelic_rpm'
|
98
|
+
gem 'rails_12factor', require: false
|
99
|
+
gem 'memcachier', require: false
|
100
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
# For heroku
|
3
|
+
ruby '2.1.3'
|
4
|
+
|
5
|
+
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
6
|
+
gem 'rails', github: 'rails/rails', branch: '4-1-stable'
|
7
|
+
# Use postgresql as the database for Active Record
|
8
|
+
gem 'pg'
|
9
|
+
# Use SCSS for stylesheets
|
10
|
+
gem 'sass-rails', '< 5.0.0'
|
11
|
+
gem 'sprockets'
|
12
|
+
# Use Uglifier as compressor for JavaScript assets
|
13
|
+
gem 'uglifier', '>= 1.3.0'
|
14
|
+
# Use CoffeeScript for .js.coffee assets and views
|
15
|
+
gem 'coffee-rails'
|
16
|
+
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
17
|
+
# gem 'therubyracer', platforms: :ruby
|
18
|
+
|
19
|
+
# Use jquery as the JavaScript library
|
20
|
+
gem 'jquery-rails'
|
21
|
+
|
22
|
+
gem 'angularjs-rails'
|
23
|
+
gem 'font-awesome-rails'
|
24
|
+
gem 'haml-rails'
|
25
|
+
gem 'newrelic_rpm'
|
26
|
+
gem 'octokit'
|
27
|
+
gem 'faraday-http-cache'
|
28
|
+
gem 'omniauth-github'
|
29
|
+
gem 'que'
|
30
|
+
gem 'sentry-raven'
|
31
|
+
gem 'multi_json'
|
32
|
+
gem 'oj'
|
33
|
+
|
34
|
+
gem 'bourbon'
|
35
|
+
gem 'neat'
|
36
|
+
gem 'normalize-rails'
|
37
|
+
|
38
|
+
gem 'docker-api', require: 'docker'
|
39
|
+
|
40
|
+
gem 'base32'
|
41
|
+
gem 'safe_yaml'
|
42
|
+
gem 'druuid'
|
43
|
+
|
44
|
+
group :staging, :production do
|
45
|
+
gem 'rails_12factor'
|
46
|
+
gem 'unicorn'
|
47
|
+
end
|
48
|
+
|
49
|
+
group :development, :test do
|
50
|
+
gem 'byebug'
|
51
|
+
gem 'pry'
|
52
|
+
gem 'pry-rails'
|
53
|
+
gem 'rspec-rails'
|
54
|
+
gem 'dotenv-rails'
|
55
|
+
end
|
56
|
+
|
57
|
+
group :test do
|
58
|
+
gem 'capybara'
|
59
|
+
gem 'capybara-webkit'
|
60
|
+
gem 'database_rewinder'
|
61
|
+
gem 'factory_girl_rails'
|
62
|
+
gem 'launchy'
|
63
|
+
gem 'webmock'
|
64
|
+
gem 'shoulda-matchers'
|
65
|
+
gem 'timecop'
|
66
|
+
gem 'nokogiri'
|
67
|
+
end
|
68
|
+
|
69
|
+
group :development do
|
70
|
+
gem 'spring'
|
71
|
+
gem 'railroady'
|
72
|
+
end
|
73
|
+
|
74
|
+
# Use ActiveModel has_secure_password
|
75
|
+
# gem 'bcrypt', '~> 3.1.7'
|
76
|
+
|
77
|
+
# Use unicorn as the app server
|
78
|
+
# gem 'unicorn'
|
79
|
+
|
80
|
+
# Use Capistrano for deployment
|
81
|
+
# gem 'capistrano-rails', group: :development
|
82
|
+
|
83
|
+
# Use debugger
|
84
|
+
# gem 'debugger', group: [:development, :test]
|
85
|
+
|
86
|
+
# gem 'grouped', group: :development
|
@@ -0,0 +1,18 @@
|
|
1
|
+
gem 'action_args'
|
2
|
+
source 'https://rubygems.org'
|
3
|
+
|
4
|
+
group :development do
|
5
|
+
gem 'bullet'
|
6
|
+
end
|
7
|
+
|
8
|
+
ruby '2.1.2'
|
9
|
+
gemspec
|
10
|
+
|
11
|
+
platforms :ruby do
|
12
|
+
gem 'mami'
|
13
|
+
end
|
14
|
+
|
15
|
+
group :test do
|
16
|
+
gem 'database_rewinder'
|
17
|
+
gem 'capybara-webkit'
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gemfile_arranger/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'gemfile_arranger'
|
8
|
+
spec.version = GemfileArranger::VERSION
|
9
|
+
spec.authors = ['sanemat']
|
10
|
+
spec.email = ['o.gata.ken@gmail.com']
|
11
|
+
spec.summary = 'A Gemfile file scrubber for the truly insane.'
|
12
|
+
spec.description = 'Sort gems, fix indent, etc.'
|
13
|
+
spec.homepage = 'https://github.com/sanemat/gemfile_arranger'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'parser', '~> 2.2.0.pre.8'
|
22
|
+
spec.add_dependency 'unparser'
|
23
|
+
spec.add_dependency 'safe_yaml'
|
24
|
+
spec.add_dependency 'thor'
|
25
|
+
spec.add_development_dependency 'unindent'
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
spec.add_development_dependency 'test-unit'
|
29
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'gemfile_arranger'
|
2
|
+
require 'gemfile_arranger/version'
|
3
|
+
require 'thor'
|
4
|
+
require 'safe_yaml/load'
|
5
|
+
require 'unparser'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
module GemfileArranger
|
9
|
+
class InitConfig < Thor::Group
|
10
|
+
include Thor::Actions
|
11
|
+
SHORT_DESCRIPTION = 'Generate a simple .gemfile_arranger.yml, placed in the current directory'
|
12
|
+
|
13
|
+
def self.source_root
|
14
|
+
Pathname
|
15
|
+
.new(__FILE__)
|
16
|
+
.dirname
|
17
|
+
.join('templates')
|
18
|
+
.expand_path
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_gemfile_arranger_yml
|
22
|
+
copy_file '.gemfile_arranger.yml'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class CLI < Thor
|
27
|
+
default_task :arrange
|
28
|
+
|
29
|
+
desc 'version', "Print the gemfile_arranger's version information"
|
30
|
+
def version
|
31
|
+
puts "Gemfile Arranger version #{VERSION}"
|
32
|
+
end
|
33
|
+
map %w(-v --version) => :version
|
34
|
+
|
35
|
+
desc 'arrange', 'Arrange given Gemfile'
|
36
|
+
option :gemfile, default: 'Gemfile', desc: 'The location of the Gemfile(5)'
|
37
|
+
option :auto_correct, type: :boolean, aliases: '-a', desc: 'Auto-correct Gemfile(5)'
|
38
|
+
def arrange
|
39
|
+
code = gemfile_contents(options[:gemfile])
|
40
|
+
|
41
|
+
buffer = Parser::Source::Buffer.new('(gemfile_arranger arrange)')
|
42
|
+
buffer.source = code
|
43
|
+
parser = Parser::CurrentRuby.new
|
44
|
+
ast = parser.parse(buffer)
|
45
|
+
|
46
|
+
sort_gems_in_group = Traverse::SortGemsInGroup.new
|
47
|
+
rewrited_ast = sort_gems_in_group.process(ast)
|
48
|
+
|
49
|
+
sort_priority_gems_in_group = Traverse::SortPriorityGemsInGroup.new(config['priority_gem'])
|
50
|
+
rewrited_ast = sort_priority_gems_in_group.process(rewrited_ast)
|
51
|
+
|
52
|
+
sort_block = Traverse::SortBlock.new(config['block_order'])
|
53
|
+
rewrited_ast = sort_block.process(rewrited_ast)
|
54
|
+
|
55
|
+
rewrited_gemfile = Unparser.unparse(rewrited_ast)
|
56
|
+
if options[:auto_correct]
|
57
|
+
rewrite_gemfile(rewrited_gemfile, options[:gemfile])
|
58
|
+
puts "Rewrite Gemfile compete! #{options[:gemfile]}"
|
59
|
+
else
|
60
|
+
puts rewrited_gemfile
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'show-config', 'Print applying configuration'
|
65
|
+
def show_config
|
66
|
+
puts config
|
67
|
+
end
|
68
|
+
|
69
|
+
desc 'show-base-config', 'Print original base configuration'
|
70
|
+
def show_base_config
|
71
|
+
puts base_config
|
72
|
+
end
|
73
|
+
|
74
|
+
register(InitConfig, 'init', 'init', InitConfig::SHORT_DESCRIPTION)
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def base_config
|
79
|
+
base_config_path = file_path
|
80
|
+
.dirname
|
81
|
+
.join('..', '..', 'config', '.gemfile_arranger.base.yml')
|
82
|
+
.expand_path
|
83
|
+
fail "Can not read base config: #{base_config_path}" unless base_config_path.file?
|
84
|
+
|
85
|
+
base_config_contents = base_config_path.read
|
86
|
+
SafeYAML.load(base_config_contents) || {}
|
87
|
+
end
|
88
|
+
|
89
|
+
def user_config
|
90
|
+
user_config_path = root_path
|
91
|
+
.join('.gemfile_arranger.yml')
|
92
|
+
.expand_path
|
93
|
+
return {} unless user_config_path.file?
|
94
|
+
|
95
|
+
user_config_contents = user_config_path.read
|
96
|
+
SafeYAML.load(user_config_contents) || {}
|
97
|
+
end
|
98
|
+
|
99
|
+
def config
|
100
|
+
base_config.merge(user_config)
|
101
|
+
end
|
102
|
+
|
103
|
+
def gemfile_contents(filename)
|
104
|
+
gemfile_path = root_path
|
105
|
+
.join(filename)
|
106
|
+
.expand_path
|
107
|
+
fail "Can not read Gemfile: #{gemfile_path}" unless gemfile_path.file?
|
108
|
+
gemfile_path.read
|
109
|
+
end
|
110
|
+
|
111
|
+
def root_path
|
112
|
+
Pathname.pwd
|
113
|
+
end
|
114
|
+
|
115
|
+
def file_path
|
116
|
+
Pathname.new(__FILE__)
|
117
|
+
end
|
118
|
+
|
119
|
+
def rewrite_gemfile(contents, filename)
|
120
|
+
root_path
|
121
|
+
.join(filename)
|
122
|
+
.expand_path
|
123
|
+
.write(contents + "\n")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module GemfileArranger
|
2
|
+
module Testing
|
3
|
+
# NOTE: Too slow(140X slower).
|
4
|
+
# ast: 0.00487 seconds
|
5
|
+
# contents: 0.678528 seconds
|
6
|
+
def contents_to_ast(contents)
|
7
|
+
buffer = Parser::Source::Buffer.new('(contents_to_ast)')
|
8
|
+
buffer.source = contents
|
9
|
+
parser = Parser::CurrentRuby.new
|
10
|
+
parser.parse(buffer)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module GemfileArranger
|
2
|
+
module Traverse
|
3
|
+
class SortBlock < Parser::AST::Processor
|
4
|
+
def initialize(keys)
|
5
|
+
@keys = Array(keys).dup.map(&:to_sym)
|
6
|
+
end
|
7
|
+
|
8
|
+
def on_begin(node)
|
9
|
+
sorted_block = sort_block_with_keys(node, @keys)
|
10
|
+
node.updated(:begin, sorted_block) if node != sorted_block
|
11
|
+
end
|
12
|
+
|
13
|
+
def sort_block_with_keys(node, keys)
|
14
|
+
node.children.sort_by.with_index do |child, i|
|
15
|
+
_, gem_name, *_ = child.children
|
16
|
+
key_index = keys.index(gem_name) || keys.length
|
17
|
+
[key_index, i]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module GemfileArranger
|
2
|
+
module Traverse
|
3
|
+
class SortGemsInGroup < Parser::AST::Processor
|
4
|
+
def on_block(node)
|
5
|
+
sorted_block = sort_gems_in_group(node)
|
6
|
+
node.updated(:block, sorted_block) if node != sorted_block
|
7
|
+
end
|
8
|
+
|
9
|
+
def sort_gems_in_group(node)
|
10
|
+
send_node, args_node, body_node = node.children
|
11
|
+
|
12
|
+
return node if send_node.children[1] != :group
|
13
|
+
return node if body_node.type != :begin
|
14
|
+
gems = body_node.children.sort_by.with_index do |child, i|
|
15
|
+
gem_name = child.children[2].children[0]
|
16
|
+
[gem_name, i]
|
17
|
+
end
|
18
|
+
return node if body_node.children == gems
|
19
|
+
|
20
|
+
sorted_body_node = body_node.updated(:begin, gems)
|
21
|
+
[send_node, args_node, sorted_body_node]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GemfileArranger
|
2
|
+
module Traverse
|
3
|
+
class SortPriorityGemsInGroup < Parser::AST::Processor
|
4
|
+
def initialize(keys)
|
5
|
+
@keys = Array(keys).dup.map(&:to_s)
|
6
|
+
end
|
7
|
+
|
8
|
+
def on_block(node)
|
9
|
+
sorted_block = sort_gems_in_group_with_keys(node, @keys)
|
10
|
+
node.updated(:block, sorted_block) if node != sorted_block
|
11
|
+
end
|
12
|
+
|
13
|
+
def sort_gems_in_group_with_keys(node, keys)
|
14
|
+
send_node, args_node, body_node = node.children
|
15
|
+
return node if send_node.children[1] != :group
|
16
|
+
return node if body_node.type != :begin
|
17
|
+
gems = body_node.children.sort_by.with_index do |child, i|
|
18
|
+
gem_name = child.children[2].children[0]
|
19
|
+
key_index = keys.index(gem_name) || keys.length
|
20
|
+
[key_index, i]
|
21
|
+
end
|
22
|
+
return node if body_node.children == gems
|
23
|
+
|
24
|
+
sorted_body_node = body_node.updated(:begin, gems)
|
25
|
+
[send_node, args_node, sorted_body_node]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestingTest < Test::Unit::TestCase
|
4
|
+
include AST::Sexp
|
5
|
+
include GemfileArranger::Testing
|
6
|
+
|
7
|
+
test 'Equal contents_to_ast' do
|
8
|
+
contents = <<-EOS.unindent
|
9
|
+
gem 'bar'
|
10
|
+
gem 'action_args'
|
11
|
+
source 'https://rubygems.org'
|
12
|
+
ruby '2.1.5'
|
13
|
+
EOS
|
14
|
+
ast = \
|
15
|
+
s(:begin,
|
16
|
+
s(:send, nil, :gem,
|
17
|
+
s(:str, 'bar')),
|
18
|
+
s(:send, nil, :gem,
|
19
|
+
s(:str, 'action_args')),
|
20
|
+
s(:send, nil, :source,
|
21
|
+
s(:str, 'https://rubygems.org')),
|
22
|
+
s(:send, nil, :ruby,
|
23
|
+
s(:str, '2.1.5')))
|
24
|
+
|
25
|
+
assert do
|
26
|
+
contents_to_ast(contents) == ast
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TraverseSortBlockTest < Test::Unit::TestCase
|
4
|
+
include AST::Sexp
|
5
|
+
include GemfileArranger::Testing
|
6
|
+
|
7
|
+
test 'Sort by large categories' do
|
8
|
+
# ----
|
9
|
+
# gem 'bar'
|
10
|
+
# gem 'action_args'
|
11
|
+
# source 'https://rubygems.org'
|
12
|
+
# ruby '2.1.5'
|
13
|
+
# ----
|
14
|
+
ast = \
|
15
|
+
s(:begin,
|
16
|
+
s(:send, nil, :gem,
|
17
|
+
s(:str, 'bar')),
|
18
|
+
s(:send, nil, :gem,
|
19
|
+
s(:str, 'action_args')),
|
20
|
+
s(:send, nil, :source,
|
21
|
+
s(:str, 'https://rubygems.org')),
|
22
|
+
s(:send, nil, :ruby,
|
23
|
+
s(:str, '2.1.5')))
|
24
|
+
|
25
|
+
# ----
|
26
|
+
# source 'https://rubygems.org'
|
27
|
+
# ruby '2.1.5'
|
28
|
+
# gem 'bar'
|
29
|
+
# gem 'action_args'
|
30
|
+
# ----
|
31
|
+
ast_expected = \
|
32
|
+
s(:begin,
|
33
|
+
s(:send, nil, :source,
|
34
|
+
s(:str, 'https://rubygems.org')),
|
35
|
+
s(:send, nil, :ruby,
|
36
|
+
s(:str, '2.1.5')),
|
37
|
+
s(:send, nil, :gem,
|
38
|
+
s(:str, 'bar')),
|
39
|
+
s(:send, nil, :gem,
|
40
|
+
s(:str, 'action_args')))
|
41
|
+
|
42
|
+
block_order = %w(source ruby gemspec gem group)
|
43
|
+
sort_block = GemfileArranger::Traverse::SortBlock.new(block_order)
|
44
|
+
|
45
|
+
assert do
|
46
|
+
sort_block.process(ast) == ast_expected
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'Sort by large categories with contents' do
|
51
|
+
contents = <<-EOS.unindent
|
52
|
+
gem 'bar'
|
53
|
+
gem 'action_args'
|
54
|
+
source 'https://rubygems.org'
|
55
|
+
ruby '2.1.5'
|
56
|
+
EOS
|
57
|
+
|
58
|
+
expected = <<-EOS.unindent
|
59
|
+
source 'https://rubygems.org'
|
60
|
+
ruby '2.1.5'
|
61
|
+
gem 'bar'
|
62
|
+
gem 'action_args'
|
63
|
+
EOS
|
64
|
+
|
65
|
+
block_order = %w(source ruby gemspec gem group)
|
66
|
+
sort_block = GemfileArranger::Traverse::SortBlock.new(block_order)
|
67
|
+
|
68
|
+
assert do
|
69
|
+
sort_block.process(contents_to_ast(contents)) == contents_to_ast(expected)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TraverseSorGemsInGroupTest < Test::Unit::TestCase
|
4
|
+
include AST::Sexp
|
5
|
+
include GemfileArranger::Testing
|
6
|
+
|
7
|
+
test 'Sort gems in group with contents' do
|
8
|
+
contents = <<-EOS.unindent
|
9
|
+
gem 'bar'
|
10
|
+
source 'https://rubygems.org'
|
11
|
+
group :development do
|
12
|
+
gem 'foo'
|
13
|
+
gem 'baz'
|
14
|
+
end
|
15
|
+
ruby '2.1.5'
|
16
|
+
EOS
|
17
|
+
|
18
|
+
expected = <<-EOS.unindent
|
19
|
+
gem 'bar'
|
20
|
+
source 'https://rubygems.org'
|
21
|
+
group :development do
|
22
|
+
gem 'baz'
|
23
|
+
gem 'foo'
|
24
|
+
end
|
25
|
+
ruby '2.1.5'
|
26
|
+
EOS
|
27
|
+
|
28
|
+
sort_block = GemfileArranger::Traverse::SortGemsInGroup.new
|
29
|
+
|
30
|
+
assert do
|
31
|
+
sort_block.process(contents_to_ast(contents)) == contents_to_ast(expected)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
test 'No effect to single gem in group' do
|
36
|
+
contents = <<-EOS.unindent
|
37
|
+
gem 'bar'
|
38
|
+
source 'https://rubygems.org'
|
39
|
+
group :development do
|
40
|
+
gem 'single'
|
41
|
+
end
|
42
|
+
ruby '2.1.5'
|
43
|
+
EOS
|
44
|
+
|
45
|
+
expected = <<-EOS.unindent
|
46
|
+
gem 'bar'
|
47
|
+
source 'https://rubygems.org'
|
48
|
+
group :development do
|
49
|
+
gem 'single'
|
50
|
+
end
|
51
|
+
ruby '2.1.5'
|
52
|
+
EOS
|
53
|
+
|
54
|
+
sort_block = GemfileArranger::Traverse::SortGemsInGroup.new
|
55
|
+
|
56
|
+
assert do
|
57
|
+
sort_block.process(contents_to_ast(contents)) == contents_to_ast(expected)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TraverseSorPriorityGemsInGroupTest < Test::Unit::TestCase
|
4
|
+
include AST::Sexp
|
5
|
+
include GemfileArranger::Testing
|
6
|
+
|
7
|
+
test 'Sort priority gems in group with contents' do
|
8
|
+
contents = <<-EOS.unindent
|
9
|
+
gem 'bar'
|
10
|
+
source 'https://rubygems.org'
|
11
|
+
group :development do
|
12
|
+
gem 'foo'
|
13
|
+
gem 'priority-2nd'
|
14
|
+
gem 'priority-1st'
|
15
|
+
gem 'baz'
|
16
|
+
end
|
17
|
+
ruby '2.1.5'
|
18
|
+
EOS
|
19
|
+
|
20
|
+
expected = <<-EOS.unindent
|
21
|
+
gem 'bar'
|
22
|
+
source 'https://rubygems.org'
|
23
|
+
group :development do
|
24
|
+
gem 'priority-1st'
|
25
|
+
gem 'priority-2nd'
|
26
|
+
gem 'foo'
|
27
|
+
gem 'baz'
|
28
|
+
end
|
29
|
+
ruby '2.1.5'
|
30
|
+
EOS
|
31
|
+
priority_gems = %w(priority-1st priority-2nd)
|
32
|
+
|
33
|
+
sort_block = GemfileArranger::Traverse::SortPriorityGemsInGroup.new(priority_gems)
|
34
|
+
|
35
|
+
assert do
|
36
|
+
sort_block.process(contents_to_ast(contents)) == contents_to_ast(expected)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gemfile_arranger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- sanemat
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: parser
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.2.0.pre.8
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.2.0.pre.8
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: unparser
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: safe_yaml
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: unindent
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.7'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.7'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: test-unit
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Sort gems, fix indent, etc.
|
126
|
+
email:
|
127
|
+
- o.gata.ken@gmail.com
|
128
|
+
executables:
|
129
|
+
- gemfile_arrange
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".hound.yml"
|
135
|
+
- ".rubocop-todo.yml"
|
136
|
+
- ".rubocop.yml"
|
137
|
+
- ".tachikoma.yml"
|
138
|
+
- ".travis.yml"
|
139
|
+
- Gemfile
|
140
|
+
- LICENSE.txt
|
141
|
+
- README.md
|
142
|
+
- Rakefile
|
143
|
+
- bin/gemfile_arrange
|
144
|
+
- config/.gemfile_arranger.base.yml
|
145
|
+
- example.txt
|
146
|
+
- examples/idobata.io.Gemfile
|
147
|
+
- examples/pigeon.tachikoma.io.Gemfile
|
148
|
+
- examples/sort-example.Gemfile
|
149
|
+
- gemfile_arranger.gemspec
|
150
|
+
- lib/gemfile_arranger.rb
|
151
|
+
- lib/gemfile_arranger/cli.rb
|
152
|
+
- lib/gemfile_arranger/templates/.gemfile_arranger.yml
|
153
|
+
- lib/gemfile_arranger/testing.rb
|
154
|
+
- lib/gemfile_arranger/traverse/sort_block.rb
|
155
|
+
- lib/gemfile_arranger/traverse/sort_gems_in_group.rb
|
156
|
+
- lib/gemfile_arranger/traverse/sort_priority_gems_in_group.rb
|
157
|
+
- lib/gemfile_arranger/version.rb
|
158
|
+
- test/helper.rb
|
159
|
+
- test/test_testing.rb
|
160
|
+
- test/test_traverse_sort_block.rb
|
161
|
+
- test/test_traverse_sort_gems_in_group.rb
|
162
|
+
- test/test_traverse_sort_priority_gems_in_group.rb
|
163
|
+
homepage: https://github.com/sanemat/gemfile_arranger
|
164
|
+
licenses:
|
165
|
+
- MIT
|
166
|
+
metadata: {}
|
167
|
+
post_install_message:
|
168
|
+
rdoc_options: []
|
169
|
+
require_paths:
|
170
|
+
- lib
|
171
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
requirements: []
|
182
|
+
rubyforge_project:
|
183
|
+
rubygems_version: 2.2.2
|
184
|
+
signing_key:
|
185
|
+
specification_version: 4
|
186
|
+
summary: A Gemfile file scrubber for the truly insane.
|
187
|
+
test_files:
|
188
|
+
- test/helper.rb
|
189
|
+
- test/test_testing.rb
|
190
|
+
- test/test_traverse_sort_block.rb
|
191
|
+
- test/test_traverse_sort_gems_in_group.rb
|
192
|
+
- test/test_traverse_sort_priority_gems_in_group.rb
|