diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bebd39f..fc21b96 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,4 +43,3 @@ jobs: ./cc-test-reporter after-build --exit-code 0 env: CC_TEST_REPORTER_ID: 903dc1a761aaec438bc9f39467e2cb4a2ea332bdb65241b37abef6338c5e6326 - - run: bundle exec rspec diff --git a/htmx-rails.gemspec b/htmx-rails.gemspec index a303fad..e0ea975 100644 --- a/htmx-rails.gemspec +++ b/htmx-rails.gemspec @@ -24,6 +24,7 @@ Gem::Specification.new do |spec| # Development dependencies. spec.add_development_dependency 'generator_spec' + spec.add_development_dependency 'psych', '>= 5.1.1.1' # pinned due to https://github.com/ruby/psych/issues/655 spec.add_development_dependency 'rake' spec.add_development_dependency 'reek' spec.add_development_dependency 'rspec' diff --git a/lib/generators/htmx/install_generator.rb b/lib/generators/htmx/install_generator.rb index 3008dcc..3cafd74 100644 --- a/lib/generators/htmx/install_generator.rb +++ b/lib/generators/htmx/install_generator.rb @@ -5,15 +5,20 @@ module Generators class InstallGenerator < ::Rails::Generators::Base WEBPACKER_SETUP = "require('htmx.org')\n" SPROCKETS_SETUP = "//= require htmx\n" + IMPORTMAP_SETUP = "import \"htmx.org\"\n" - desc 'Prep application.js to include HTMX installation for Webpacker or Sprockets' + desc 'Prep application.js to include HTMX installation for Webpacker, Sprockets or Importmap' # Setup HTMX def setup - if webpacker? + if importmap? + setup_importmap + elsif webpacker? setup_webpacker - else + elsif sprockets? setup_sprockets + else + raise 'No known asset pipeline detected' end end @@ -23,10 +28,30 @@ def webpacker? !!defined?(Webpacker) end + def sprockets? + !!defined?(Sprockets) + end + + def importmap? + !!defined?(Importmap) + end + def manifest(javascript_dir) Pathname.new(destination_root).join(javascript_dir, 'application.js') end + def setup_importmap + run 'bin/importmap pin htmx.org' + + manifest = manifest('app/javascript') + + if manifest.exist? + append_file manifest, "\n#{IMPORTMAP_SETUP}" + else + create_file manifest, IMPORTMAP_SETUP + end + end + def setup_sprockets manifest = manifest('app/assets/javascripts') @@ -38,7 +63,7 @@ def setup_sprockets end def setup_webpacker - `yarn add htmx.org` + run 'yarn add htmx.org' manifest = manifest(webpack_source_path) diff --git a/spec/generators/install_generator_spec.rb b/spec/generators/install_generator_spec.rb index 105eeaf..716d9d8 100644 --- a/spec/generators/install_generator_spec.rb +++ b/spec/generators/install_generator_spec.rb @@ -14,6 +14,12 @@ after(:all) { FileUtils.rm_rf destination_root } context 'with Sprockets' do + before do + hide_const('Webpacker') + hide_const('Importmap') + stub_const('Sprockets', Module.new) + end + context 'when `application.js` exists' do before do generate_application_js('/app/assets/javascripts') @@ -42,10 +48,12 @@ context 'with Webpacker' do before do stub_const('Webpacker', Module.new) + hide_const('Sprockets') + hide_const('Importmap') - Htmx::Generators::InstallGenerator - .any_instance - .stub(:webpack_source_path) + expect_any_instance_of(Htmx::Generators::InstallGenerator) + .to receive(:webpack_source_path) + .at_least(1).time .and_return(File.join("#{destination_root}/app/javascript/packs")) end @@ -73,4 +81,48 @@ end end end + + context 'with Importmap' do + before do + hide_const('Webpacker') + hide_const('Sprockets') + stub_const('Importmap', Module.new) + end + + context 'when `application.js` exists' do + before do + generate_application_js('/app/javascript') + end + + it 'updates file with htmx import' do + run_generator + assert_file( + 'app/javascript/application.js', + "\n#{Htmx::Generators::InstallGenerator::IMPORTMAP_SETUP}" + ) + end + end + + context 'when `application.js` does not exists' do + it 'creates `application.js` file with htmx import' do + run_generator + assert_file( + 'app/javascript/application.js', + Htmx::Generators::InstallGenerator::IMPORTMAP_SETUP + ) + end + end + end + + context 'with no asset pipeline' do + before do + hide_const('Webpacker') + hide_const('Sprockets') + hide_const('Importmap') + end + + it 'raise an error' do + expect { run_generator }.to raise_error('No known asset pipeline detected') + end + end end