diff --git a/lib/sprig.rb b/lib/sprig.rb index 8658178..715075f 100644 --- a/lib/sprig.rb +++ b/lib/sprig.rb @@ -17,6 +17,8 @@ module Sprig autoload :SprigRecordStore, 'sprig/sprig_record_store' autoload :Data, 'sprig/data' autoload :Seed, 'sprig/seed' + autoload :Task, 'sprig/task' + autoload :Railtie, 'sprig/railtie' class << self def configuration @@ -36,3 +38,5 @@ def logger end end end + +require 'sprig/railtie' if defined?(Rails) diff --git a/lib/sprig/railtie.rb b/lib/sprig/railtie.rb new file mode 100644 index 0000000..44016d9 --- /dev/null +++ b/lib/sprig/railtie.rb @@ -0,0 +1,7 @@ +module Sprig + class Railtie < Rails::Railtie + rake_tasks do + load "tasks/sprig.rake" + end + end +end diff --git a/lib/sprig/task.rb b/lib/sprig/task.rb new file mode 100644 index 0000000..d87fe12 --- /dev/null +++ b/lib/sprig/task.rb @@ -0,0 +1,5 @@ +module Sprig + module Task + autoload :PurgeSeeds, 'sprig/task/purge_seeds' + end +end diff --git a/lib/sprig/task/purge_seeds.rb b/lib/sprig/task/purge_seeds.rb new file mode 100644 index 0000000..aa89ca4 --- /dev/null +++ b/lib/sprig/task/purge_seeds.rb @@ -0,0 +1,55 @@ +module Sprig + module Task + class PurgeSeeds + include Logging + + def perform + log_info "Preparing to purge seeds from the #{Rails.env} environment. To purge a different environment, specify the environment as an environment variable (e.g. RAILS_ENV=production)." + stop 'No seed files to delete. Aborting.' unless seed_files.any? + list_seed_files + stop 'Purge aborted.'unless deletion_confirmed? + delete_seed_files + log_info 'Seed files deleted.' + end + + private + + def stop(error_message) + log_error error_message + abort + end + + def list_seed_files + log_debug 'Files to be deleted:' + seed_files.each do |filename| + log_debug "- #{File.basename(filename)}" + end + end + + def seed_files + @seed_files ||= Dir.glob("#{seed_directory}/*") + end + + def seed_directory + Sprig.configuration.directory + end + + def deletion_confirmed? + log_debug "Are you sure you want to delete these files? (Type 'yes' to confirm.)" + input = $stdin.gets.chomp + input == 'yes' ? true : false + end + + def delete_seed_files + seed_files.each do |file| + if File.directory?(file) + FileUtils.rm_rf(file) + else + File.delete(file) + end + end + end + + end + end +end diff --git a/lib/tasks/sprig.rake b/lib/tasks/sprig.rake new file mode 100644 index 0000000..6ed3e40 --- /dev/null +++ b/lib/tasks/sprig.rake @@ -0,0 +1,10 @@ +namespace :db do + namespace :seed do + + desc 'Purge seed files for specified environment' + task :purge do + Sprig::Task::PurgeSeeds.new.perform + end + + end +end diff --git a/spec/lib/sprig/railtie_spec.rb b/spec/lib/sprig/railtie_spec.rb new file mode 100644 index 0000000..b9eec3f --- /dev/null +++ b/spec/lib/sprig/railtie_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Sprig::Railtie do + subject { described_class.instance } + + its(:railtie_name) { should == 'sprig_railtie'} +end diff --git a/spec/lib/sprig/task/purge_seeds_spec.rb b/spec/lib/sprig/task/purge_seeds_spec.rb new file mode 100644 index 0000000..cb0468f --- /dev/null +++ b/spec/lib/sprig/task/purge_seeds_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe Sprig::Task::PurgeSeeds do + subject { described_class.new } + + before do + stub_rails_root + end + + describe "#perform" do + context "when no seed files are present" do + it "aborts with an error message" do + log_should_receive :error, with: 'No seed files to delete. Aborting.' + + expect { + subject.perform + }.to raise_error SystemExit + end + end + + context "when seed files are present" do + around do |example| + load_seeds('posts.yml', &example) + end + + context "and deletion is not confirmed" do + it "aborts with an error message" do + log_should_receive :error, with: 'Purge aborted.' + + expect { + fake_stdin_gets 'no' do + subject.perform + end + }.to raise_error SystemExit + end + end + + context "and deletion is confirmed" do + it "deletes the seed files" do + Dir.glob("#{Sprig.configuration.directory}/*").should_not be_empty + + fake_stdin_gets 'yes' do + subject.perform + end + + Dir.glob("#{Sprig.configuration.directory}/*").should be_empty + end + end + end + end +end diff --git a/spec/lib/tasks/sprig_rake_spec.rb b/spec/lib/tasks/sprig_rake_spec.rb new file mode 100644 index 0000000..c8be61b --- /dev/null +++ b/spec/lib/tasks/sprig_rake_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe "db:seed:purge" do + include_context "rake" + + let(:task) { double('Sprig::Task::PurgeSeeds') } + + before do + Sprig::Task::PurgeSeeds.stub(:new).and_return(task) + end + + it "purges seed files" do + task.should_receive(:perform) + subject.invoke + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a195cd5..76732e1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -94,3 +94,12 @@ def load_seeds(*files) `rm ./spec/fixtures/db/seeds/#{env}/#{file}` end end + +def fake_stdin_gets(input) + begin + $stdin = double('STDIN', gets: input) + yield + ensure + $stdin = STDIN + end +end diff --git a/spec/support/shared_context/rake.rb b/spec/support/shared_context/rake.rb new file mode 100644 index 0000000..93f2f42 --- /dev/null +++ b/spec/support/shared_context/rake.rb @@ -0,0 +1,19 @@ +require "rake" + +shared_context "rake" do + let(:rake) { Rake::Application.new } + let(:task_name) { self.class.top_level_description } + let(:task_path) { "lib/tasks/sprig" } + subject { rake[task_name] } + + def loaded_files_excluding_current_rake_file + $".reject {|file| file == Rails.root.join("#{task_path}.rake").to_s } + end + + before do + Rails.stub(:root).and_return(Pathname.new("#{File.dirname(__FILE__)}/../../..")) + Rake.application = rake + Sprig::Railtie.instance.load_tasks + Rake::Task.define_task(:environment) + end +end