squasher 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03bf510487b316ab7771766ef9605f8a8269bfed
4
+ data.tar.gz: e01e6ba2390d5dabcc0a7fd24d7cbafb4c0f4549
5
+ SHA512:
6
+ metadata.gz: 399e73be169b440d181fd4ab2283bb11fd75226e5a8d3b3ecba6b4c4b1b3808b7908c993f5a5ec44d5e258920a70c568db8773823bff7aef49fe7979f250167c
7
+ data.tar.gz: 092b138e42c74d278a97247e1fbf679ea5c2bba65e0379aaa1ac555205d2e9ac4937a53608f010764f47be788fbbff895acb1656e0b358822728d7d59ac827fa
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in squasher.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Sergey Pchelincev
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
+ # Squasher
2
+
3
+ Squasher is a compressor of the old migrations in rails application. If you works on big project with lots of migrations
4
+ every `rake db:migrate` takes a few seconds, creating of a new database might takes a few minutes. It's just because rails load
5
+ all this files. Squasher instead remove all this migrations and create one single migration with a final state of a database.
6
+
7
+ ## Installation
8
+
9
+ You should not add this to Gemfile. Just standalone installation:
10
+
11
+ $ gem install squasher
12
+
13
+ @Note if you use Rbenv don't forget to run `rbenv rehash`.
14
+
15
+ ## Usage
16
+
17
+ Once you install gem you will get `squasher` command.
18
+
19
+ $ squasher 2014 #compress all migrations which were created prior to 2014 year
20
+
21
+ You can tell `squasher` a more detailed date, for example:
22
+
23
+ $ squasher 2013/12 #prior December 2013
24
+ $ squasher 2013/12/19 #prior 19 December 2013
25
+
26
+ ## Requirements
27
+
28
+ It works and was tested on Ruby 1.9.3+ and Rails 3.2+. Also it requires a valid configuration in `config/database.yml` and using Ruby format in `db/schema.rb`(default rails usecase).
29
+ If some migration insert data(create a ActiveRecord model records) you will lost this code in a new created migration, but `squasher` will ask you to leave tmp database which will have all inserted information. Using this database you could again add this inserting into a new migration or create/update `config/seed.rb` file(expected place for this stuff).
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it
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 new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/squasher ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ require 'squasher'
3
+
4
+ case ARGV[0]
5
+ when 'clean' then Squasher.clean
6
+ when /\A\d{4}/ then Squasher.squash(ARGV[0])
7
+ else
8
+ Squasher.tell(:usage)
9
+ end
data/lib/squasher.rb ADDED
@@ -0,0 +1,57 @@
1
+ module Squasher
2
+ extend self
3
+
4
+ autoload :Cleaner, 'squasher/cleaner'
5
+ autoload :Config, 'squasher/config'
6
+ autoload :Render, 'squasher/render'
7
+ autoload :Worker, 'squasher/worker'
8
+
9
+ def squash(raw_date)
10
+ parts = raw_date.to_s.split('/').map(&:to_i)
11
+ date = Time.new(*parts)
12
+ Worker.process(date)
13
+ end
14
+
15
+ def clean
16
+ Cleaner.process
17
+ end
18
+
19
+ def rake(command, description = nil)
20
+ tell(description) if description
21
+ system("bundle exec rake #{ command }")
22
+ end
23
+
24
+ def ask(*args)
25
+ tell(*args)
26
+ $stdin.gets[0].downcase == 'y'
27
+ end
28
+
29
+ def tell(key, options = {})
30
+ message = messages.fetch(key.to_s)
31
+ message = colorize(message)
32
+ options.each { |key, value| message.gsub!(":#{ key }", value) }
33
+ puts message
34
+ end
35
+
36
+ def error(*args)
37
+ tell(*args)
38
+ exit
39
+ end
40
+
41
+ private
42
+
43
+ def messages
44
+ return @messages if @messages
45
+
46
+ require 'json'
47
+ path = File.join(File.dirname(__FILE__), 'squasher/messages.json')
48
+ @messages = JSON.load(File.open(path))
49
+ end
50
+
51
+ def colorize(message)
52
+ message.gsub(/\:(\w+)\{([^}]+)\}/) do |match|
53
+ color_code = { "red" => "031", "green" => "032", "yellow" => "033" }[$1]
54
+ "\033[#{ color_code }m#{ $2 }\033[039m"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,43 @@
1
+ require 'fileutils'
2
+
3
+ module Squasher
4
+ class Cleaner
5
+ MIGRATION_NAME = 'squasher_clean'
6
+
7
+ def self.process(*args)
8
+ new(*args).process
9
+ end
10
+
11
+ def process
12
+ Squasher.error(:migration_folder_missing) unless config.migrations_folder?
13
+
14
+ migration_file = config.migration_file(now_timestamp, MIGRATION_NAME)
15
+ if prev_migration
16
+ FileUtils.mv(prev_migration, migration_file)
17
+ else
18
+ File.open(migration_file, 'wb') do |stream|
19
+ stream << ::Squasher::Render.render(MIGRATION_NAME, config)
20
+ end
21
+ end
22
+ Squasher.rake("db:migrate", :db_cleaning)
23
+ end
24
+
25
+ private
26
+
27
+ def config
28
+ @config ||= Squasher::Config.new
29
+ end
30
+
31
+ def prev_migration
32
+ return @prev_migration if defined?(@prev_migration)
33
+
34
+ @prev_migration = config.migration_files.detect do |file|
35
+ File.basename(file).include?(MIGRATION_NAME)
36
+ end
37
+ end
38
+
39
+ def now_timestamp
40
+ Time.now.strftime("%Y%m%d%H%M%S")
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,82 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+
4
+ module Squasher
5
+ class Config
6
+ def initialize
7
+ @root_path = Dir.pwd
8
+ end
9
+
10
+ def schema_file
11
+ @schema_file ||= from_root('db', 'schema.rb')
12
+ end
13
+
14
+ def migration_files
15
+ Dir.glob(File.join(migrations_folder, '**.rb'))
16
+ end
17
+
18
+ def migration_file(timestamp, migration_name)
19
+ File.join(migrations_folder, "#{ timestamp }_#{ migration_name }.rb")
20
+ end
21
+
22
+ def migrations_folder?
23
+ Dir.exists?(migrations_folder)
24
+ end
25
+
26
+ def dbconfig?
27
+ !dbconfig.nil?
28
+ end
29
+
30
+ def stub_dbconfig
31
+ return unless dbconfig?
32
+
33
+ list = [dbconfig_file, schema_file]
34
+ list.each do |file|
35
+ next unless File.exists?(file)
36
+ FileUtils.mv file, "#{ file }.sbackup"
37
+ end
38
+ update_dbconfig_file
39
+
40
+ yield
41
+
42
+ ensure
43
+ list.each do |file|
44
+ next unless File.exists?("#{ file }.sbackup")
45
+ FileUtils.mv "#{ file }.sbackup", file
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :root_path
52
+
53
+ def from_root(*subfolders)
54
+ File.join(root_path, *subfolders)
55
+ end
56
+
57
+ def migrations_folder
58
+ @migrations_folder ||= from_root('db', 'migrate')
59
+ end
60
+
61
+ def dbconfig_file
62
+ @dbconfig_file ||= from_root('config', 'database.yml')
63
+ end
64
+
65
+ def dbconfig
66
+ return @dbconfig if defined?(@dbconfig)
67
+ return @dbconfig = nil unless File.exists?(dbconfig_file)
68
+
69
+ @dbconfig = YAML.load_file(dbconfig_file)['development']
70
+ if @dbconfig && !@dbconfig.empty?
71
+ @dbconfig['database'] = 'squasher'
72
+ @dbconfig = { 'development' => @dbconfig }
73
+ else
74
+ @dbconfig = nil
75
+ end
76
+ end
77
+
78
+ def update_dbconfig_file
79
+ File.open(dbconfig_file, 'wb') { |stream| stream.write dbconfig.to_yaml }
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,19 @@
1
+ {
2
+ "keep_database" : "Squasher created `:green{squasher}` database for it needs.\nIt might be useful if some deleted migration insert data into a database.\nLeft it(:green{yes} / :red{no})?",
3
+
4
+ "apply_clean": "Do you want to clean your database from an old schema migrations records(:red{yes}/:green{no})?",
5
+
6
+ "migration_folder_missing" : "The folder with migrations is missing.\nAre you sure in the :red{root of a rails} application?",
7
+
8
+ "no_migrations" : "There are no migrations in the folder prior :red{:date}",
9
+
10
+ "dbconfig_invalid" : "Squasher could not find `:green{database.yml}` with working development environment",
11
+
12
+ "db_create": "Squasher is creating a tmp database",
13
+
14
+ "db_migrate": "Squasher is appling a migrations on a tmp database",
15
+
16
+ "db_cleaning": "Squasher is appling a clean migration",
17
+
18
+ "usage": "Example usage:\n :green{squasher} :yellow{year[/month][/day]} #squash migrations prior to a specified date\n :green{squasher} :yellow{clean} #generate or update a cleaning migration and apply it\n :green{squasher} :yellow{info} #show this message"
19
+ }
@@ -0,0 +1,46 @@
1
+ require 'erb'
2
+
3
+ module Squasher
4
+ class Render
5
+ def self.render(*args)
6
+ new(*args).render
7
+ end
8
+
9
+ attr_reader :name, :config
10
+
11
+ def initialize(name, config)
12
+ @name = name
13
+ @config = config
14
+ end
15
+
16
+ def render
17
+ ERB.new(template("#{ name }.rb"), nil, '-').result(binding)
18
+ end
19
+
20
+ def each_schema_line
21
+ File.open(config.schema_file, 'r') do |stream|
22
+ inside_schema = false
23
+ stream.each_line do |line|
24
+ if inside_schema
25
+ next if line.empty?
26
+ # reach eand of schema
27
+ break if line.index("end") == 0
28
+ yield line[2...-1]
29
+ else
30
+ inside_schema = true if line.include?("ActiveRecord::Schema")
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def template(name)
39
+ path = File.join(File.dirname(__FILE__), "templates/#{ name }.erb")
40
+ template = File.open(path, "rb")
41
+ content = template.read
42
+ template.close
43
+ content
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,11 @@
1
+ class InitSchema < ActiveRecord::Migration
2
+ def up
3
+ <%- each_schema_line do |line| -%>
4
+ <%= line %>
5
+ <%- end -%>
6
+ end
7
+
8
+ def down
9
+ raise "Can not revert initial migration"
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ class SquasherClean < ActiveRecord::Migration
2
+ class SchemaMigration < ActiveRecord::Base
3
+ end
4
+
5
+ def up
6
+ migrations = Dir.glob(File.join(File.dirname(__FILE__), '**.rb'))
7
+ versions = migrations.map { |file| file.split('/').last[/\A\d+/] }
8
+ SchemaMigration.where("version NOT IN (?)", versions).delete_all
9
+ end
10
+
11
+ def down
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Squasher
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,74 @@
1
+ require 'fileutils'
2
+
3
+ module Squasher
4
+ class Worker
5
+ attr_reader :date
6
+
7
+ def self.process(*args)
8
+ new(*args).process
9
+ end
10
+
11
+ def initialize(date)
12
+ @date = date
13
+ end
14
+
15
+ def process
16
+ check!
17
+
18
+ result = under_squash_env do
19
+ File.open(config.migration_file(finish_timestamp, :init_schema), 'wb') do |stream|
20
+ stream << ::Squasher::Render.render(:init_schema, config)
21
+ end
22
+
23
+ migrations.each { |file| FileUtils.rm(file) }
24
+
25
+ Squasher.rake("db:drop") unless Squasher.ask(:keep_database)
26
+ end
27
+ Squasher.clean if result && Squasher.ask(:apply_clean)
28
+ end
29
+
30
+ private
31
+
32
+ def config
33
+ @config ||= ::Squasher::Config.new
34
+ end
35
+
36
+ def check!
37
+ Squasher.error(:migration_folder_missing) unless config.migrations_folder?
38
+ Squasher.error(:dbconfig_invalid) unless config.dbconfig?
39
+ if migrations.empty?
40
+ print_date = date.strftime("%Y/%m/%d")
41
+ Squasher.error(:no_migrations, :date => print_date)
42
+ end
43
+ end
44
+
45
+ def migrations
46
+ return @migrations if @migrations
47
+
48
+ @migrations = config.migration_files.select { |file| before_date?(get_timestamp(file)) }
49
+ end
50
+
51
+ def get_timestamp(file)
52
+ File.basename(file)[/\A\d+/]
53
+ end
54
+
55
+ def before_date?(timestamp)
56
+ @point ||= date.strftime("%Y%m%d").to_i
57
+ return unless timestamp
58
+ timestamp[0...8].to_i < @point
59
+ end
60
+
61
+ def finish_timestamp
62
+ @finish_timestamp ||= get_timestamp(migrations.last)
63
+ end
64
+
65
+ def under_squash_env
66
+ config.stub_dbconfig do
67
+ if Squasher.rake("db:drop db:create", :db_create) &&
68
+ Squasher.rake("db:migrate VERSION=#{ finish_timestamp }", :db_migrate)
69
+ yield
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,8 @@
1
+ development:
2
+ database: app_development
3
+ user: root
4
+ password: password
5
+ test:
6
+ database: app_test
7
+ user: root
8
+ password: password
@@ -0,0 +1,4 @@
1
+ test:
2
+ database: app_test
3
+ user: root
4
+ password: password
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended to check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(:version => 20130613090053) do
15
+
16
+ create_table "cities", :force => true do |t|
17
+ t.string "name"
18
+ t.datetime "created_at", :null => false
19
+ t.datetime "updated_at", :null => false
20
+ end
21
+
22
+ create_table "managers", :force => true do |t|
23
+ t.string "email"
24
+ t.string "password_digest"
25
+ t.datetime "created_at", :null => false
26
+ t.datetime "updated_at", :null => false
27
+ end
28
+
29
+ create_table "offices", :force => true do |t|
30
+ t.string "name"
31
+ t.string "address"
32
+ t.string "phone"
33
+ t.text "description"
34
+ t.integer "capacity"
35
+ t.datetime "created_at", :null => false
36
+ t.datetime "updated_at", :null => false
37
+ t.integer "manager_id"
38
+ t.integer "city_id"
39
+ end
40
+
41
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe Squasher::Cleaner do
5
+ let(:expected_file) { File.join(fake_root, 'db', 'migrate', '20140102030405_squasher_clean.rb') }
6
+
7
+ before do
8
+ Time.stub(:now => Time.new(2014, 1, 2, 3, 4, 5))
9
+ Squasher.stub(:rake).with("db:migrate", :db_cleaning)
10
+ end
11
+
12
+ after do
13
+ FileUtils.rm(expected_file)
14
+ end
15
+
16
+ it 'create a new migration' do
17
+ Squasher::Cleaner.any_instance.stub(:prev_migration => nil)
18
+ Squasher.clean
19
+
20
+ expect(clean_migrations).to include(expected_file)
21
+ File.open(expected_file) do |stream|
22
+ content = stream.read
23
+ expect(content).to include("SquasherClean")
24
+ end
25
+ end
26
+
27
+ it 'update an existing migration' do
28
+ Squasher.clean
29
+
30
+ expect(clean_migrations.size).to be(1)
31
+ expect(clean_migrations.first).to eq(expected_file)
32
+
33
+ FileUtils.touch(File.join(fake_root, 'db/migrate/20140101010101_squasher_clean.rb'))
34
+ end
35
+
36
+ def clean_migrations
37
+ Dir.glob(File.join(fake_root, '**/*_squasher_clean.rb'))
38
+ end
39
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Squasher::Config do
4
+ let(:config) { described_class.new }
5
+
6
+ context '.dbconfig?' do
7
+ subject(:result) { config.dbconfig? }
8
+
9
+ it 'a file is exists and it has a valid content' do
10
+ expect(result).to be_true
11
+ end
12
+
13
+ it 'a file is exists but doesnt have a valid content' do
14
+ config.stub(:dbconfig_file => File.join(fake_root, 'config', 'invalid_database.yml'))
15
+
16
+ expect(result).to be_false
17
+ end
18
+
19
+ it 'a file is not exists' do
20
+ config.stub(:dbconfig_file => File.join(fake_root, 'config', 'not_existed.yml'))
21
+
22
+ expect(result).to be_false
23
+ end
24
+ end
25
+
26
+ context '#stub_dbconfig' do
27
+ it 'add required db config file' do
28
+ config.stub_dbconfig do
29
+ File.open(File.join(fake_root, 'config', 'database.yml')) do |stream|
30
+ content = stream.read
31
+ expect(content).to include ("database: squasher")
32
+ expect(content).to include("development:")
33
+ end
34
+ end
35
+ end
36
+
37
+ it 'recover original schema and db config files if some error raised' do
38
+ begin
39
+ config.stub_dbconfig do
40
+ expect(file_exists?('config', 'database.yml')).to be_true
41
+ expect(file_exists?('config', 'database.yml.sbackup')).to be_true
42
+
43
+ raise RuntimeError, "Unexpected system error"
44
+ end
45
+ rescue RuntimeError
46
+ expect(file_exists?('config', 'database.yml')).to be_true
47
+ expect(file_exists?('config', 'database.yml.sbackup')).to be_false
48
+ end
49
+ end
50
+
51
+ def file_exists?(*parts)
52
+ File.exists?(File.join(fake_root, *parts))
53
+ end
54
+ end
55
+
56
+ specify { expect(config.migration_file(1230, :sample)).to eq(File.join(fake_root, 'db', 'migrate', '1230_sample.rb')) }
57
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe Squasher::Worker do
5
+ context 'failed on #check!' do
6
+ let(:worker) { described_class.new(Time.new(2012, 6, 20)) }
7
+
8
+ it 'command was run not in application root' do
9
+ Squasher::Config.any_instance.stub(:migrations_folder? => false)
10
+
11
+ expect_exit_with(:migration_folder_missing)
12
+ end
13
+
14
+ it 'db configuration is invalid' do
15
+ Squasher::Config.any_instance.stub(:dbconfig? => false)
16
+
17
+ expect_exit_with(:dbconfig_invalid)
18
+ end
19
+
20
+ it 'matched migrations was not found' do
21
+ expect_exit_with(:no_migrations, :date => "2012/06/20")
22
+ end
23
+
24
+ def expect_exit_with(*args)
25
+ expect(Squasher).to receive(:error).with(*args).and_call_original
26
+ expect { worker.process }.to raise_error(SystemExit)
27
+ end
28
+ end
29
+
30
+ it 'create a new squashed migration & remove selected migrations' do
31
+ worker = described_class.new(Time.new(2014))
32
+ worker.stub(:under_squash_env).and_yield.and_return(true)
33
+ new_migration_path = File.join(Dir.tmpdir, 'init_schema.rb')
34
+ Squasher::Config.any_instance.stub(:migration_file).with('2013122900', :init_schema).and_return(new_migration_path)
35
+
36
+ FileUtils.should_receive(:rm).with(File.join(fake_root, 'db', 'migrate', '201312090000_first_migration.rb'))
37
+ FileUtils.should_receive(:rm).with(File.join(fake_root, 'db', 'migrate', '2013122900_second_migration.rb'))
38
+ Squasher.should_receive(:ask).with(:keep_database).and_return(false)
39
+ Squasher.should_receive(:rake).with("db:drop")
40
+ Squasher.should_receive(:ask).with(:apply_clean).and_return(true)
41
+ Squasher.should_receive(:clean)
42
+
43
+ worker.process
44
+
45
+ expect(File.exists?(new_migration_path)).to be_true
46
+ File.open(new_migration_path) do |stream|
47
+ content = stream.read
48
+ expect(content).to include("InitSchema")
49
+ expect(content).to include('create_table "managers", :force => true do |t|')
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Squasher do
4
+ context '.squash' do
5
+ specify { expected_covert("2013/12/23", Time.new(2013, 12, 23)) }
6
+ specify { expected_covert("2013", Time.new(2013, 1, 1)) }
7
+
8
+ def expected_covert(input, expected)
9
+ expect(Squasher::Worker).to receive(:process).with(expected)
10
+ Squasher.squash(input)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'bundler/setup'
2
+ Bundler.require
3
+
4
+ def fake_root
5
+ @fake_root ||= File.join(File.dirname(__FILE__), 'fake_app')
6
+ end
7
+
8
+ RSpec.configure do |config|
9
+ config.order = 'random'
10
+ config.before do
11
+ Squasher::Config.any_instance.stub(:root_path => fake_root)
12
+ end
13
+ end
data/squasher.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'squasher/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "squasher"
8
+ spec.version = Squasher::VERSION
9
+ spec.authors = ["Sergey Pchelincev"]
10
+ spec.email = ["mail@sergeyp.me"]
11
+ spec.description = %q{Squash your old migrations}
12
+ spec.summary = %q{Squash your old migrations}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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_development_dependency "bundler", ">= 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", ">= 2.14"
24
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: squasher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sergey Pchelincev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ description: Squash your old migrations
56
+ email:
57
+ - mail@sergeyp.me
58
+ executables:
59
+ - squasher
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - .rspec
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/squasher
70
+ - lib/squasher.rb
71
+ - lib/squasher/cleaner.rb
72
+ - lib/squasher/config.rb
73
+ - lib/squasher/messages.json
74
+ - lib/squasher/render.rb
75
+ - lib/squasher/templates/init_schema.rb.erb
76
+ - lib/squasher/templates/squasher_clean.rb.erb
77
+ - lib/squasher/version.rb
78
+ - lib/squasher/worker.rb
79
+ - spec/fake_app/config/database.yml
80
+ - spec/fake_app/config/invalid_database.yml
81
+ - spec/fake_app/db/migrate/201312090000_first_migration.rb
82
+ - spec/fake_app/db/migrate/2013122900_second_migration.rb
83
+ - spec/fake_app/db/migrate/20140101010101_squasher_clean.rb
84
+ - spec/fake_app/db/migrate/20140110_third_migration.rb
85
+ - spec/fake_app/db/schema.rb
86
+ - spec/lib/squasher/cleaner_spec.rb
87
+ - spec/lib/squasher/config_spec.rb
88
+ - spec/lib/squasher/worker_spec.rb
89
+ - spec/lib/squasher_spec.rb
90
+ - spec/spec_helper.rb
91
+ - squasher.gemspec
92
+ homepage: ''
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.0.14
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Squash your old migrations
116
+ test_files:
117
+ - spec/fake_app/config/database.yml
118
+ - spec/fake_app/config/invalid_database.yml
119
+ - spec/fake_app/db/migrate/201312090000_first_migration.rb
120
+ - spec/fake_app/db/migrate/2013122900_second_migration.rb
121
+ - spec/fake_app/db/migrate/20140101010101_squasher_clean.rb
122
+ - spec/fake_app/db/migrate/20140110_third_migration.rb
123
+ - spec/fake_app/db/schema.rb
124
+ - spec/lib/squasher/cleaner_spec.rb
125
+ - spec/lib/squasher/config_spec.rb
126
+ - spec/lib/squasher/worker_spec.rb
127
+ - spec/lib/squasher_spec.rb
128
+ - spec/spec_helper.rb
129
+ has_rdoc: