Skip to content

Commit

Permalink
Merge pull request #15 from nikolalsvk/add-check-option
Browse files Browse the repository at this point in the history
Add --check option
  • Loading branch information
nikolalsvk authored Aug 12, 2017
2 parents af01483 + d43fd0b commit 01669ed
Show file tree
Hide file tree
Showing 11 changed files with 384 additions and 81 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.gem
*.ordinare
/coverage
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

[![Build Status](https://semaphoreci.com/api/v1/nikolalsvk/ordinare/branches/master/shields_badge.svg)](https://semaphoreci.com/nikolalsvk/ordinare)
[![Gem Version](https://badge.fury.io/rb/ordinare.svg)](https://badge.fury.io/rb/ordinare)
[![codecov](https://codecov.io/gh/nikolalsvk/ordinare/branch/master/graph/badge.svg)](https://codecov.io/gh/nikolalsvk/ordinare)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md#5-make-a-pull-request)

Ordinare sorts gems in your Gemfile alphabetically
Expand Down
2 changes: 1 addition & 1 deletion bin/ordinare
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ require "ordinare"
if ARGV.size > 0
Ordinare.parse_args
else
Ordinare.sort
Ordinare::Sort.sort_gemfile
end
70 changes: 13 additions & 57 deletions lib/ordinare.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
require "ordinare/version"
require "ordinare/sort"
require "ordinare/check"
require "optparse"

module Ordinare
Expand All @@ -13,6 +15,7 @@ def parse_args
overwrite = true
version = nil
help = nil
check = nil

OptionParser.new do |opts|
opts.banner = "Usage: ordinare inside your Rails project"
Expand All @@ -27,6 +30,10 @@ def parse_args
overwrite = false
end

opts.on("-c", "--check", "Check if Gemfile is sorted properly") do
check = true
end

opts.on("-v", "--version", "Check gem version") do
puts Ordinare::VERSION
version = true
Expand All @@ -38,64 +45,13 @@ def parse_args
end
end.parse!

Ordinare.sort(overwrite, path) unless version || help
end

def sort(overwrite = true, path = "Gemfile")
unless File.file?(path)
abort("No Gemfile found in the current directory, is this a Rails project with Gemfile?")
end

content = File.readlines(path)
return if version || help

ranges_to_sort = find_ranges_of_gems(content)

ranges_to_sort.each do |range|
content[range[:start_index]..range[:end_index]] =
content[range[:start_index]..range[:end_index]].sort
end

path = "#{path}.ordinare" unless overwrite

File.open(path, "w+") do |file|
content.each { |line| file.puts(line) }
end

puts "Your sorted Gemfile can be found at #{path} path"
end

def find_ranges_of_gems(content)
gems = content.each_with_index.map do |line, index|
if line.strip.start_with?("gem ")
index
end
end

ranges_to_sort = []
gems.each_with_index do |gem, index|
current_range = if ranges_to_sort.last && !ranges_to_sort.last[:end_index]
ranges_to_sort.last
else
{ :start_index => nil, :end_index => nil }
end
start_index = current_range[:start_index]
end_index = current_range[:end_index]

if gem && !gems[index - 1] && gems[index + 1]
current_range[:start_index] = index
current_range[:end_index] = index if index == gems.length - 1

ranges_to_sort << current_range unless ranges_to_sort.any? { |range| range[:start_index] == index }
elsif gem && gems[index - 1] && !gems[index + 1]
ranges_to_sort.map do |range|
if range[:start_index] == start_index
range[:end_index] = index
end

range
end
end
if check
Ordinare::Check.gemfile_sorted?(path)
else
puts path
Ordinare::Sort.sort_gemfile(overwrite, path)
end
ranges_to_sort
end
end
28 changes: 28 additions & 0 deletions lib/ordinare/check.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Ordinare
class Check
def self.gemfile_sorted?(path = "Gemfile")
new(path).gemfile_sorted?
end

def initialize(path)
@path = path
end

def gemfile_sorted?
unless File.file?(@path)
abort "No Gemfile found in the current directory, is this a Rails project with Gemfile?"
end

ordered_content = Ordinare::Sort.sort_content(@path, File.readlines(@path))

read_content = File.readlines(@path)

if read_content == ordered_content
puts "Gemfile is sorted properly"
true
else
abort "Gemfile is not sorted"
end
end
end
end
85 changes: 85 additions & 0 deletions lib/ordinare/sort.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
module Ordinare
class Sort
def self.sort_gemfile(overwrite = true, path = "Gemfile")
new(overwrite, path).sort_gemfile
end

def self.sort_content(path = "Gemfile", content)
new(false, path).sort_content(content)
end

def initialize(overwrite, path)
@overwrite = overwrite
@read_path = path
@write_path = overwrite ? @read_path : "#{path}.ordinare"
end

def sort_gemfile
unless File.file?(@read_path)
abort "No Gemfile found in the current directory, is this a Rails project with Gemfile?"
end

read_content = File.readlines(@read_path)

ordered_content = sort_content(read_content)

write_to_a_file(ordered_content)
end

def sort_content(content)
ranges_to_sort = find_ranges_of_gems(content)

ranges_to_sort.each do |range|
content[range[:start_index]..range[:end_index]] =
content[range[:start_index]..range[:end_index]].sort
end

content
end

private

def find_ranges_of_gems(content)
gems = content.each_with_index.map do |line, index|
if line.strip.start_with?("gem ")
index
end
end

ranges_to_sort = []
gems.each_with_index do |gem, index|
current_range = if ranges_to_sort.last && !ranges_to_sort.last[:end_index]
ranges_to_sort.last
else
{ :start_index => nil, :end_index => nil }
end
start_index = current_range[:start_index]
end_index = current_range[:end_index]

if gem && !gems[index - 1] && gems[index + 1]
current_range[:start_index] = index
current_range[:end_index] = index if index == gems.length - 1

ranges_to_sort << current_range unless ranges_to_sort.any? { |range| range[:start_index] == index }
elsif gem && gems[index - 1] && !gems[index + 1]
ranges_to_sort.map do |range|
if range[:start_index] == start_index
range[:end_index] = index
end

range
end
end
end
ranges_to_sort
end

def write_to_a_file(content)
File.open(@write_path, "w+") do |file|
content.each { |line| file.puts(line) }
end

puts "Your sorted Gemfile can be found at #{@write_path} path"
end
end
end
2 changes: 1 addition & 1 deletion lib/ordinare/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Ordinare
VERSION = "0.3.0"
VERSION = "0.4.0"
end
60 changes: 60 additions & 0 deletions spec/fixtures/ordered_gemfile/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
source 'http://rubygems.org'

ruby '2.3.1'

gem 'rails', '4.2.7.1'

gem 'coffee-rails', "~> 4.0.1"
gem 'uglifier', "~> 2.7.2"

gem 'compass-rails', '~> 2.0'
gem 'sass-rails', '~> 4.0.0'

group :test do
gem "rspec-rails", "~>3.0"
gem 'capybara', '~> 2.6.2'

gem 'cucumber-rails', '~> 1.4.0', require: false # require: false is needed for cucumber-rails

gem 'selenium-webdriver', '~> 2.45'

# Launchy is needed by Capybara, e.g. save_and_open command needs Launchy to open a browser
gem 'connection_pool', "~> 2.1"
gem 'database_cleaner', '~> 1.1'
gem 'email_spec', '~> 1.6.0'
gem 'launchy', '~> 2.4', '>= 2.4.3'
gem 'rack-test', "~> 0.6.2"
gem 'timecop', '~> 0.6.3'

# required for CircleCI automatic test balancing
gem 'rspec_junit_formatter'
end

group :development, :test do
gem 'pry-byebug'
end

gem 'js-routes', '~> 1.2.5'
gem 'therubyracer', '~> 0.12.2', platforms: :ruby

# Color utilities needed for landing page
gem 'color', '~> 1.8'

gem 'transit-ruby', '~> 0.8'
gem 'uuidtools', '~> 2.1'

# Markdown parser
gem 'redcarpet', '~> 3.3', '>= 3.3.4'

gem 'twilio-ruby', '~> 4.11.1'

gem 'intercom', '~> 3.5.10'

gem 'simple_token_authentication', '~> 1.0'

gem 'daemons'

gem "select2-rails"

gem 'client_side_validations'

29 changes: 29 additions & 0 deletions spec/ordinare/check_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "spec_helper"

describe Ordinare::Check do
describe "#gemfile_sorted?" do
context "no Gemfile found" do
it "aborts with message" do
expect {
described_class.gemfile_sorted?("spec/fixtures/no_gemfile")
}.to raise_error(SystemExit)
end
end

context "Gemfile is sorted properly" do
it "returns true" do
gemfile_sorted = described_class.gemfile_sorted?("spec/fixtures/ordered_gemfile/Gemfile")

expect(gemfile_sorted).to be_truthy
end
end

context "Gemfile is not sorted properly" do
it "raises an exception" do
expect {
described_class.gemfile_sorted?("spec/fixtures/complex_gemfile/Gemfile")
}.to raise_error(SystemExit)
end
end
end
end
40 changes: 40 additions & 0 deletions spec/ordinare/sort_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require "spec_helper"
require "fileutils"

describe Ordinare::Sort do
describe "#sort_gemfile" do
context "no Gemfile found" do
it "aborts with message" do
expect {
Ordinare::Sort.sort_gemfile(false, "spec/fixtures/no_gemfile")
}.to raise_error(SystemExit)
end
end

context "Gemfile found" do
it "sorts basic Gemfile" do
basic_gemfile = "spec/fixtures/basic_gemfile/Gemfile"
Ordinare::Sort.sort_gemfile(false, basic_gemfile)

same_files = FileUtils.identical?("#{basic_gemfile}.ordered", "#{basic_gemfile}.ordinare")
expect(same_files).to be_truthy
end

it "sorts Gemfile with groups" do
group_gemfile = "spec/fixtures/group_gemfile/Gemfile"
Ordinare::Sort.sort_gemfile(false, group_gemfile)

same_files = FileUtils.identical?("#{group_gemfile}.ordered", "#{group_gemfile}.ordinare")
expect(same_files).to be_truthy
end

it "sorts complicated Gemfile" do
complex_gemfile = "spec/fixtures/complex_gemfile/Gemfile"
Ordinare::Sort.sort_gemfile(false, complex_gemfile)

same_files = FileUtils.identical?("#{complex_gemfile}.ordered", "#{complex_gemfile}.ordinare")
expect(same_files).to be_truthy
end
end
end
end
Loading

0 comments on commit 01669ed

Please sign in to comment.