Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ rvm:
- 2.4.0

env:
- "RAILS_VERSION=5.0.2"
- "RAILS_VERSION=5.0.3"
26 changes: 16 additions & 10 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,31 @@ require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task :default => :ci

task :ci => ['generate_test_gem', 'spec'] do

end

task :generate_test_gem => ['engine_cart:setup'] do
system("rm -rf .internal_test_gem")
gem 'rails'
destination = EngineCart.destination

rails_path = Gem.bin_path('railties', 'rails')
system("rm -rf #{destination}")

if ENV['RAILS_VERSION']
gem 'rails', ENV['RAILS_VERSION']
else
gem 'rails'
end

Bundler.with_clean_env do
system("#{rails_path} plugin new internal_test_gem")
system('bundle exec rails plugin new /tmp/internal_test_gem')
end
system("mv internal_test_gem .internal_test_gem")
system("mv /tmp/internal_test_gem #{destination}")

IO.write(".internal_test_gem/internal_test_gem.gemspec", File.open(".internal_test_gem/internal_test_gem.gemspec") {|f| f.read.gsub(/FIXME/, "DONTCARE")})
IO.write(".internal_test_gem/internal_test_gem.gemspec", File.open(".internal_test_gem/internal_test_gem.gemspec") {|f| f.read.gsub(/TODO/, "DONTCARE")})
IO.write(".internal_test_gem/internal_test_gem.gemspec", File.open(".internal_test_gem/internal_test_gem.gemspec") {|f| f.read.gsub(/.*homepage.*/, "")})
IO.write("#{destination}/internal_test_gem.gemspec", File.open("#{destination}/internal_test_gem.gemspec") {|f| f.read.gsub(/FIXME/, "DONTCARE")})
IO.write("#{destination}/internal_test_gem.gemspec", File.open("#{destination}/internal_test_gem.gemspec") {|f| f.read.gsub(/TODO/, "DONTCARE")})
IO.write("#{destination}/internal_test_gem.gemspec", File.open("#{destination}/internal_test_gem.gemspec") {|f| f.read.gsub(/.*homepage.*/, "")})

Rake::Task['engine_cart:inject_gemfile_extras'].invoke
EngineCart.within_test_app do
Expand All @@ -48,11 +55,10 @@ task :generate_test_gem => ['engine_cart:setup'] do
system %Q{echo '\ngem "sprockets", "~> 2.11.0"\n' >> Gemfile}
end
Bundler.clean_system "bundle update --quiet"
system "echo 'require \"engine_cart/rake_task\"\n' >> Rakefile"

system "echo 'require \"engine_cart/rake_task\"\n' >> Rakefile"
system("bundle exec rake engine_cart:prepare")
Bundler.clean_system "bundle install --quiet"
end
end

task :default => :ci
36 changes: 8 additions & 28 deletions lib/engine_cart.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
require 'engine_cart/configuration'
require "engine_cart/version"
require 'engine_cart/fingerprint'
require 'engine_cart/version'
require 'engine_cart/gemfile_stanza'
require 'bundler'

module EngineCart
require "engine_cart/engine" if defined? Rails
require 'engine_cart/engine' if defined? Rails

def self.load_application! path = nil
require File.expand_path("config/environment", path || EngineCart.destination)
def self.load_application!(path = nil)
require File.expand_path('config/environment', path || EngineCart.destination)
end

def self.within_test_app
Expand All @@ -18,30 +19,9 @@ def self.within_test_app
end
end

def self.fingerprint
@fingerprint || (@fingerprint_proc || method(:default_fingerprint)).call
end

def self.fingerprint= fingerprint
@fingerprint = fingerprint
end

def self.fingerprint_proc= fingerprint_proc
@fingerprint_proc = fingerprint_proc
end

def self.rails_fingerprint_proc extra_files = []
lambda do
EngineCart.default_fingerprint + (Dir.glob("./db/migrate/*") + Dir.glob("./lib/generators/**/**") + Dir.glob("./spec/test_app_templates/**/**") + extra_files).map {|f| File.mtime(f) }.max.to_s
end
end

def self.default_fingerprint
EngineCart.env_fingerprint + (Dir.glob("./*.gemspec") + [Bundler.default_gemfile.to_s, Bundler.default_lockfile.to_s]).map {|f| File.mtime(f) }.max.to_s
end

def self.env_fingerprint
{ 'RUBY_DESCRIPTION' => RUBY_DESCRIPTION, 'BUNDLE_GEMFILE' => Bundler.default_gemfile.to_s }.reject { |k, v| v.nil? || v.empty? }.to_s
def self.update?(fingerprint)
return true if EngineCart.fingerprint_saved.nil? || fingerprint.nil?
EngineCart.fingerprint_saved != fingerprint
end

def self.configuration(options = {})
Expand Down
24 changes: 12 additions & 12 deletions lib/engine_cart/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ def initialize(options = {})
end

def load_configs(config_files)
config = default_config

(default_configuration_paths + config_files.compact).each do |p|
path = File.expand_path(p)
next unless File.exist? path
config.merge!(read_config(path))
@config ||= begin
cfg = default_config
(default_configuration_paths + config_files.compact).each do |p|
path = File.expand_path(p)
next unless File.exist? path
cfg.merge!(read_config(path))
end
cfg
end

config
end

##
Expand Down Expand Up @@ -79,12 +79,12 @@ def default_config

def read_config(config_file)
$stdout.puts "Loading configuration from #{config_file}" if verbose?
config = YAML.load(ERB.new(IO.read(config_file)).result(binding))
unless config
cfg = YAML.load(ERB.new(IO.read(config_file)).result(binding))
unless cfg
$stderr.puts "Unable to parse config #{config_file}" if verbose?
return {}
end
convert_keys(config)
convert_keys(cfg)
end

def convert_keys(hash)
Expand All @@ -95,4 +95,4 @@ def default_configuration_paths
['~/.engine_cart.yml', '.engine_cart.yml']
end
end
end
end
96 changes: 96 additions & 0 deletions lib/engine_cart/fingerprint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
require 'bundler'
require 'digest/md5'

module EngineCart

def self.fingerprint_current
(@fingerprint_proc || method(:default_fingerprint)).call
end

def self.fingerprint_saved
File.read(EngineCart.fingerprint_file)
rescue StandardError
nil
end

def self.fingerprint_save(fp)
fp ||= EngineCart.fingerprint_current
File.open(EngineCart.fingerprint_file, 'w') { |f| f.write(fp) }
end

def self.fingerprint_update
EngineCart.fingerprint = EngineCart.fingerprint_current
EngineCart.fingerprint_save EngineCart.fingerprint
end

def self.fingerprint_file
File.expand_path('.generated_engine_cart', EngineCart.destination)
end

def self.fingerprint
@fingerprint || EngineCart.fingerprint_current
end

def self.fingerprint=(fp)
@fingerprint = fp
end

def self.fingerprint_proc=(fingerprint_proc)
@fingerprint_proc = fingerprint_proc
end

def self.rails_fingerprint_proc(extra_files = [])
lambda do
EngineCart.default_fingerprint + EngineCart.rails_fingerprint(extra_files)
end
end

def self.rails_fingerprint(extra_files = [])
EngineCart.files_digest(EngineCart.rails_files + extra_files)
end

def self.rails_files
Dir.glob([
'./db/migrate/*',
'./lib/generators/**/**',
'./spec/test_app_templates/**/**'
])
end

def self.default_fingerprint
EngineCart.env_fingerprint + EngineCart.gem_fingerprint
end

def self.gem_fingerprint
EngineCart.files_digest EngineCart.gem_files
end

def self.gem_files
Dir.glob('./*.gemspec') + [EngineCart.bundle_gemfile, EngineCart.bundle_lockfile]
end

def self.env_fingerprint
{
'RUBY_DESCRIPTION' => RUBY_DESCRIPTION,
'BUNDLE_GEMFILE' => EngineCart.bundle_gemfile
}.reject { |k, v| v.nil? || v.empty? }.to_s
end

def self.bundle_gemfile
@bundle_gemfile ||= Bundler.default_gemfile.to_s
end

def self.bundle_lockfile
@bundle_gemfile ||= Bundler.default_lockfile.to_s
end

def self.files_digest(files)
files_digests = files.collect {|f| file_digest(f) }.join
Digest::MD5.hexdigest(files_digests)
end

def self.file_digest(f)
File.file?(f) ? Digest::MD5.hexdigest(File.read(f)) : ''
end

end
8 changes: 2 additions & 6 deletions lib/engine_cart/tasks/engine_cart.rake
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ namespace :engine_cart do

desc "Create the test rails app"
task :generate, [:fingerprint] => [:setup] do |t, args|
original_fingerprint = args[:fingerprint]
args.with_defaults(:fingerprint => EngineCart.fingerprint) unless original_fingerprint

f = File.expand_path('.generated_engine_cart', EngineCart.destination)
unless File.exist?(f) && File.read(f) == args[:fingerprint]
if EngineCart.update? args[:fingerprint]

# Create a new test rails app
Rake::Task['engine_cart:create_test_rails_app'].invoke
Expand All @@ -106,7 +102,7 @@ namespace :engine_cart do

Bundler.clean_system "bundle install --quiet"

File.open(File.expand_path('.generated_engine_cart', EngineCart.destination), 'w') { |f| f.write(original_fingerprint || EngineCart.fingerprint) }
EngineCart.fingerprint_update

puts "Done generating test app"
end
Expand Down
10 changes: 6 additions & 4 deletions lib/generators/engine_cart/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,20 @@ def install_engine
end
end

def ignore_test_app
def ignore_test_app(app_path = nil)
app_path ||= EngineCart.destination

# Ignore the generated test app in the gem's .gitignore file
git_root = (`git rev-parse --show-toplevel` rescue '.').strip

# If we don't have a .gitignore file already, don't worry about it
return unless File.exist? File.expand_path('.gitignore', git_root)

# If the directory is already ignored (somehow) don't worry about it
return if (system('git', 'check-ignore', TEST_APP, '-q') rescue false)
return if (system('git', 'check-ignore', app_path, '-q') rescue false)

append_file File.expand_path('.gitignore', git_root) do
"\n#{EngineCart.destination}\n"
append_file File.expand_path('.gitignore', git_root) do
"\n#{app_path}\n"
end
end

Expand Down
25 changes: 17 additions & 8 deletions spec/integration/engine_cart_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
require 'spec_helper'

describe "EngineCart powered application" do

# EngineCart.destination can be defined by various config files and options.
# The engine_cart gem contains a .engine_cart.yml file, with destination: '.internal_test_gem'
let(:destination) { EngineCart.destination }

# The test app does not use a .engine_cart.yml file, so it uses a default destination: '.internal_test_app'
let(:default_destination) { EngineCart.configuration.default_destination }

it "should have the test_app_templates pre-generated" do
expect(File).to exist File.expand_path("spec/test_app_templates", EngineCart.destination)
end

it "should ignore the test app" do
git_ignore = File.expand_path(".gitignore", EngineCart.destination)
expect(File.read(git_ignore)).to match /.internal_test_app/
expect(File.read(git_ignore)).to match /#{default_destination}/
end

it "should have a engine_cart:generate rake task available" do
Expand All @@ -27,27 +35,28 @@
it "should create a rails app when the engine_cart:generate task is invoked" do
EngineCart.within_test_app do
`rake engine_cart:generate`
expect(File).to exist(File.expand_path('.internal_test_app'))
expect(File).to exist(File.expand_path(default_destination))
end
end

it "should not recreate an existing rails app when the engine_cart:generate task is reinvoked" do
EngineCart.within_test_app do
`rake engine_cart:generate`
expect(File).to exist(File.expand_path('.internal_test_app'))
FileUtils.touch File.join('.internal_test_app', ".this_should_still_exist")
expect(File).to exist(File.expand_path(default_destination))
tmp_file_path = File.expand_path(File.join(default_destination, ".this_should_still_exist"))
FileUtils.touch tmp_file_path
`rake engine_cart:generate`
expect(File).to exist(File.expand_path(File.join('.internal_test_app', ".this_should_still_exist")))
expect(File).to exist(tmp_file_path)
end
end

it "should create a rails app when the fingerprint argument is changed" do
EngineCart.within_test_app do
`rake engine_cart:generate[this-fingerprint]`
expect(File).to exist(File.expand_path('.internal_test_app'))
FileUtils.touch File.join('.internal_test_app', ".this_should_not_exist")
expect(File).to exist(File.expand_path(default_destination))
FileUtils.touch File.join(default_destination, ".this_should_not_exist")
`rake engine_cart:generate[that-fingerprint]`
expect(File).to_not exist(File.expand_path(File.join('.internal_test_app', ".this_should_not_exist")))
expect(File).to_not exist(File.expand_path(File.join(default_destination, ".this_should_not_exist")))
end
end

Expand Down