├── .gitignore ├── .rspec ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin ├── console └── setup ├── exe └── happy_gemfile ├── happy_gemfile.gemspec ├── lib ├── happy_gemfile.rb └── happy_gemfile │ └── version.rb └── spec ├── happy_gemfile_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.idea 11 | .byebug_history -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: ruby 3 | rvm: 4 | - 2.3.0 5 | before_install: gem install bundler -v 1.12.5 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of 4 | fostering an open and welcoming community, we pledge to respect all people who 5 | contribute through reporting issues, posting feature requests, updating 6 | documentation, submitting pull requests or patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free 9 | experience for everyone, regardless of level of experience, gender, gender 10 | identity and expression, sexual orientation, disability, personal appearance, 11 | body size, race, ethnicity, age, religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic 20 | addresses, without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or 24 | reject comments, commits, code, wiki edits, issues, and other contributions 25 | that are not aligned to this Code of Conduct, or to ban temporarily or 26 | permanently any contributor for other behaviors that they deem inappropriate, 27 | threatening, offensive, or harmful. 28 | 29 | By adopting this Code of Conduct, project maintainers commit themselves to 30 | fairly and consistently applying these principles to every aspect of managing 31 | this project. Project maintainers who do not follow or enforce the Code of 32 | Conduct may be permanently removed from the project team. 33 | 34 | This code of conduct applies both within project spaces and in public spaces 35 | when an individual is representing the project or its community. 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 38 | reported by contacting a project maintainer at shaynetremblay@hotmail.com. All 39 | complaints will be reviewed and investigated and will result in a response that 40 | is deemed necessary and appropriate to the circumstances. Maintainers are 41 | obligated to maintain confidentiality with regard to the reporter of an 42 | incident. 43 | 44 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 45 | version 1.3.0, available at 46 | [http://contributor-covenant.org/version/1/3/0/][version] 47 | 48 | [homepage]: http://contributor-covenant.org 49 | [version]: http://contributor-covenant.org/version/1/3/0/ -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 MainShayne233 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HappyGemfile 2 | 3 | House keep on your Gemfile no more! Happy Gemfile is here to clean up a small fraction of the clutter in your codebase by alphabetizing your gems! 4 | 5 | ## Installation 6 | 7 | Add this line to your application's Gemfile: 8 | 9 | ```ruby 10 | gem 'happy_gemfile' 11 | ``` 12 | 13 | And then execute: 14 | 15 | $ bundle 16 | 17 | Or install it yourself with: 18 | 19 | $ gem install happy_gemfile 20 | 21 | ## Usage 22 | 23 | You can call the executable in the directory with the gemfile to be spruced up! 24 | ```bash 25 | $ happy_gemfile 26 | ``` 27 | 28 | But nothing will happen without arguments! 29 | ```bash 30 | happy_gemfile alphabetize # alphabetizes gems in place; reminds me of grade school. 31 | 32 | happy_gemfile wipe_comments # clears all, non-inline, comments; you know what you're doing, right? 33 | 34 | happy_gemfile organize_groups # places gems tidily their specified group; home sweet home! 35 | 36 | happy_gemfile all # one arg to call them all! (RECOMMENDED) 37 | 38 | ``` 39 | 40 | 41 | Alternatively, you can call the alphabetize method directly in your app, say, in your config.rb. 42 | ```ruby 43 | HappyGemfile.alphabetize 44 | 45 | HappyGemfile.wipe_comments 46 | 47 | HappyGemfile.organize_groups 48 | 49 | HappyGemfile.all 50 | 51 | ``` 52 | 53 | 54 | ## License 55 | 56 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). 57 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rspec/core/rake_task" 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => :spec 7 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | require "happy_gemfile" 5 | 6 | # You can add fixtures and/or initialization code here to make experimenting 7 | # with your gem easier. You can also use a different console, if you like. 8 | 9 | # (If you use this, don't forget to add pry to your Gemfile!) 10 | # require "pry" 11 | # Pry.start 12 | 13 | require "irb" 14 | IRB.start 15 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /exe/happy_gemfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'happy_gemfile' 4 | 5 | if ARGV.empty? 6 | puts "\nHey! I need some arguments here!\n\n"\ 7 | "You can run 'happy_gemfile all' for everything, or, if you don't trust me, you can pass any of these in:\n\n"\ 8 | "alphabetize - Organizes gems alphabetically\n"\ 9 | "wipe_comments - Removes all, non-inline comments\n"\ 10 | "organize_groups - Places everything tidily their specified group." 11 | exit 12 | end 13 | 14 | gemfile = HappyGemfile.gemfile 15 | 16 | %w(wipe_comments organize_groups alphabetize).each{|arg|gemfile = HappyGemfile.send(arg, gemfile) unless [arg, 'all'] - ARGV == [arg, 'all']} 17 | 18 | HappyGemfile.replace_gemfile gemfile 19 | -------------------------------------------------------------------------------- /happy_gemfile.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'happy_gemfile/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "happy_gemfile" 8 | spec.version = HappyGemfile::VERSION 9 | spec.authors = ["MainShayne233"] 10 | spec.email = ["shaynetremblay@hotmail.com"] 11 | 12 | spec.summary = %q{Alphabetizes your gems in your Gemfile! Makes life good!} 13 | spec.homepage = "https://github.com/MainShayne233/happy_gemfile" 14 | spec.license = "MIT" 15 | 16 | 17 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 18 | spec.bindir = "exe" 19 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 20 | spec.require_paths = ["lib"] 21 | 22 | spec.add_development_dependency "bundler", "~> 1.12" 23 | spec.add_development_dependency "rake", "~> 10.0" 24 | spec.add_development_dependency "rspec", "~> 3.0" 25 | end 26 | -------------------------------------------------------------------------------- /lib/happy_gemfile.rb: -------------------------------------------------------------------------------- 1 | require "happy_gemfile/version" 2 | 3 | module HappyGemfile 4 | 5 | def self.all 6 | gemfile = wipe_comments 7 | gemfile = organize_groups gemfile 8 | gemfile = alphabetize gemfile 9 | replace_gemfile gemfile 10 | end 11 | 12 | def self.alphabetize lines=nil 13 | 14 | lines ||= gemfile 15 | gem_groups = [[]] 16 | gem_indexes = [[]] 17 | group_count = 0 18 | in_group = false 19 | 20 | lines.each_with_index do |line, index| 21 | if is?(line, 'gem') 22 | unless in_group 23 | gem_groups[0] << line 24 | gem_indexes[0] << index 25 | else 26 | gem_groups[group_count] << line 27 | gem_indexes[group_count] << index 28 | end 29 | elsif is?(line, 'group') 30 | in_group = true 31 | group_count += 1 32 | gem_groups << [] 33 | gem_indexes << [] 34 | elsif is? line, 'end' 35 | in_group = false 36 | end 37 | end 38 | 39 | gem_groups.map{|group| group.sort}.each_with_index do |group, group_index| 40 | group.each_with_index do |line, line_index| 41 | lines[gem_indexes[group_index][line_index]] = line 42 | end 43 | end 44 | 45 | lines 46 | end 47 | 48 | def self.wipe_comments lines=nil 49 | lines ||= gemfile 50 | lines.delete_if{|line| is_comment?(line)} 51 | lines 52 | end 53 | 54 | def self.organize_groups lines=nil 55 | lines ||= gemfile 56 | groups = {general: []} 57 | current_group = :general 58 | lines.each do |line| 59 | if is? line, 'gem' 60 | groups[current_group] << line.gsub("\n", '') 61 | elsif is? line, 'group' 62 | current_group = group_name line 63 | groups[current_group] ||= [] 64 | elsif is? line, 'end' 65 | current_group = :general 66 | else 67 | groups[:not_gems] ||= [] 68 | groups[:not_gems] << line.gsub("\n", '') 69 | end 70 | end 71 | 72 | groups.each {|key, lines| lines.delete_if {|line| ["\n", ''].include? line} } 73 | 74 | organized = [] 75 | 76 | groups[:not_gems].each {|line| organized << line << "\n"} 77 | 78 | organized << "\n" 79 | 80 | groups[:general].each {|line| organized << line << "\n"} 81 | 82 | organized << "\n" 83 | 84 | (groups.keys - [:general, :not_gems]).each do |group| 85 | organized << "group #{group_line(group)} do" << "\n" 86 | groups[group].each {|line| organized << "#{line}" << "\n"} 87 | organized << 'end' << "\n\n" 88 | end 89 | organized 90 | end 91 | 92 | # HELPERS 93 | 94 | def self.is_comment? line 95 | is? line, '#' 96 | end 97 | 98 | def self.is? line, type 99 | line.split(' ').first == type 100 | end 101 | 102 | def self.group_name line 103 | line.match(/group(.*)do/) 104 | .to_a[1] 105 | .strip.gsub(', ', '_') 106 | .gsub(':', '') 107 | .to_sym 108 | end 109 | 110 | def self.group_line group 111 | group.to_s.split('_').map{|g| ":#{g}"}.join(', ') 112 | end 113 | 114 | def self.gemfile 115 | unless File.exists? "Gemfile" 116 | puts "There doesn't appear to be a Gemfile... not sure what to do." 117 | return false 118 | end 119 | File.readlines "Gemfile" 120 | end 121 | 122 | def self.replace_gemfile lines 123 | File.open("Gemfile", 'w') { |file| file.write(lines.join('')) } 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /lib/happy_gemfile/version.rb: -------------------------------------------------------------------------------- 1 | module HappyGemfile 2 | VERSION = "0.1.2" 3 | end 4 | -------------------------------------------------------------------------------- /spec/happy_gemfile_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe HappyGemfile do 4 | it 'has a version number' do 5 | expect(HappyGemfile::VERSION).not_to be nil 6 | end 7 | 8 | it 'does something useful' do 9 | expect(false).to eq(true) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) 2 | require 'happy_gemfile' 3 | --------------------------------------------------------------------------------