From 2673455f3f25e0d29f5286caed739726bee5253b Mon Sep 17 00:00:00 2001 From: Jason Meller Date: Mon, 11 Sep 2023 20:51:28 -0400 Subject: [PATCH] Add bun support --- lib/install/Procfile_for_bun.dev | 2 + .../{Procfile.dev => Procfile_for_node.dev} | 0 lib/install/bootstrap/install.rb | 39 ++++++----------- lib/install/bulma/install.rb | 19 +++------ lib/install/helpers.rb | 42 +++++++++++++++++++ lib/install/install.rb | 7 +++- lib/install/postcss/install.rb | 19 +++------ lib/install/sass/install.rb | 19 +++------ lib/install/tailwind/install.rb | 19 +++------ lib/tasks/cssbundling/build.rake | 28 ++++++++++--- 10 files changed, 108 insertions(+), 86 deletions(-) create mode 100644 lib/install/Procfile_for_bun.dev rename lib/install/{Procfile.dev => Procfile_for_node.dev} (100%) create mode 100644 lib/install/helpers.rb diff --git a/lib/install/Procfile_for_bun.dev b/lib/install/Procfile_for_bun.dev new file mode 100644 index 0000000..7eaba23 --- /dev/null +++ b/lib/install/Procfile_for_bun.dev @@ -0,0 +1,2 @@ +web: env RUBY_DEBUG_OPEN=true bin/rails server +css: bun run build:css --watch diff --git a/lib/install/Procfile.dev b/lib/install/Procfile_for_node.dev similarity index 100% rename from lib/install/Procfile.dev rename to lib/install/Procfile_for_node.dev diff --git a/lib/install/bootstrap/install.rb b/lib/install/bootstrap/install.rb index ac920f6..5966564 100644 --- a/lib/install/bootstrap/install.rb +++ b/lib/install/bootstrap/install.rb @@ -1,7 +1,10 @@ +require_relative "../helpers" +self.extend Helpers + say "Install Bootstrap with Bootstrap Icons, Popperjs/core and Autoprefixer" copy_file "#{__dir__}/application.bootstrap.scss", "app/assets/stylesheets/application.bootstrap.scss" -run "yarn add sass bootstrap bootstrap-icons @popperjs/core postcss postcss-cli autoprefixer nodemon" +run "#{bundler_cmd} add sass bootstrap bootstrap-icons @popperjs/core postcss postcss-cli autoprefixer nodemon" inject_into_file "config/initializers/assets.rb", after: /.*Rails.application.config.assets.paths.*\n/ do <<~RUBY @@ -16,32 +19,14 @@ say %(Add import * as bootstrap from "bootstrap" to your entry point JavaScript file), :red end -def add_npm_script(name, script, run_script=true) - case `npx -v`.to_f - when 7.1...8.0 - say "Add #{name} script" - run %(npm set-script #{name} "#{script}") - run %(yarn #{name}) if run_script - when (8.0..) - say "Add #{name} script" - run %(npm pkg set scripts.#{name}="#{script}") - run %(yarn #{name}) if run_script - else - say %(Add "scripts": { "#{name}": "#{script}" } to your package.json), :green - end -end - -add_npm_script("build:css:compile", "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules") -add_npm_script("build:css:prefix", "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css") -add_npm_script("build:css", "yarn build:css:compile && yarn build:css:prefix") -add_npm_script("watch:css", "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec \\\"yarn build:css\\\"", false) +add_package_json_script("build:css:compile", "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules") +add_package_json_script("build:css:prefix", "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css") +add_package_json_script("build:css", "#{bundler_run_cmd} build:css:compile && #{bundler_run_cmd} build:css:prefix") +add_package_json_script("watch:css", "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec \"#{bundler_run_cmd} build:css\"", false) gsub_file "Procfile.dev", "build:css --watch", "watch:css" -case `npx -v`.to_f -when (7.1..) - say "Add browserslist config" - run %(npm pkg set browserslist[]=defaults) -else - say %(Add "browserslist": ["defaults"] to your package.json), :green -end +package_json = JSON.parse(File.read("package.json")) +package_json["browserslist"] ||= {} +package_json["browserslist"] = ["defaults"] +File.write("package.json", JSON.pretty_generate(package_json)) diff --git a/lib/install/bulma/install.rb b/lib/install/bulma/install.rb index 96dc9be..c5276d0 100644 --- a/lib/install/bulma/install.rb +++ b/lib/install/bulma/install.rb @@ -1,18 +1,11 @@ +require_relative "../helpers" +self.extend Helpers + say "Install Bulma" copy_file "#{__dir__}/application.bulma.scss", "app/assets/stylesheets/application.bulma.scss" -run "yarn add sass bulma" +run "#{bundler_cmd} add sass bulma" say "Add build:css script" -build_script = "sass ./app/assets/stylesheets/application.bulma.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" - -case `npx -v`.to_f -when 7.1...8.0 - run %(npm set-script build:css "#{build_script}") - run %(yarn build:css) -when (8.0..) - run %(npm pkg set scripts.build:css="#{build_script}") - run %(yarn build:css) -else - say %(Add "scripts": { "build:css": "#{build_script}" } to your package.json), :green -end +add_package_json_script "build:css", + "sass ./app/assets/stylesheets/application.bulma.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" diff --git a/lib/install/helpers.rb b/lib/install/helpers.rb new file mode 100644 index 0000000..b8837f8 --- /dev/null +++ b/lib/install/helpers.rb @@ -0,0 +1,42 @@ +require 'json' + +module Helpers + def bundler_cmd + using_bun? ? "bun" : "yarn" + end + + def bundler_run_cmd + using_bun? ? "bun run" : "yarn" + end + + def using_bun? + File.exist?('bun.lockb') || (tool_exists?('bun') && !File.exist?('yarn.lock')) + end + + def tool_exists?(tool) + system "command -v #{tool} > /dev/null" + end + + def add_package_json_script(name, script, run_script=true) + if using_bun? + package_json = JSON.parse(File.read("package.json")) + package_json["scripts"] ||= {} + package_json["scripts"][name] = script + File.write("package.json", JSON.pretty_generate(package_json)) + run %(bun run #{name}) if run_script + else + case `npx -v`.to_f + when 7.1...8.0 + say "Add #{name} script" + run %(npm set-script #{name} "#{script}") + run %(yarn #{name}) if run_script + when (8.0..) + say "Add #{name} script" + run %(npm pkg set scripts.#{name}="#{script}") + run %(yarn #{name}) if run_script + else + say %(Add "scripts": { "#{name}": "#{script}" } to your package.json), :green + end + end + end +end diff --git a/lib/install/install.rb b/lib/install/install.rb index f02d3a0..321bbf7 100644 --- a/lib/install/install.rb +++ b/lib/install/install.rb @@ -1,3 +1,6 @@ +require_relative "helpers" +self.extend Helpers + say "Build into app/assets/builds" empty_directory "app/assets/builds" keep_file "app/assets/builds" @@ -41,10 +44,10 @@ end if Rails.root.join("Procfile.dev").exist? - append_to_file "Procfile.dev", "css: yarn build:css --watch\n" + append_to_file "Procfile.dev", "css: #{bundler_run_cmd} build:css --watch\n" else say "Add default Procfile.dev" - copy_file "#{__dir__}/Procfile.dev", "Procfile.dev" + copy_file "#{__dir__}/#{using_bun? ? "Procfile_for_bun" : "Procfile_for_node"}", "Procfile.dev" say "Ensure foreman is installed" run "gem install foreman" diff --git a/lib/install/postcss/install.rb b/lib/install/postcss/install.rb index 18aa4e0..d9eb5bd 100644 --- a/lib/install/postcss/install.rb +++ b/lib/install/postcss/install.rb @@ -1,18 +1,11 @@ +require_relative "../helpers" +self.extend Helpers + say "Install PostCSS w/ nesting and autoprefixer" copy_file "#{__dir__}/postcss.config.js", "postcss.config.js" copy_file "#{__dir__}/application.postcss.css", "app/assets/stylesheets/application.postcss.css" -run "yarn add postcss postcss-cli postcss-import postcss-nesting autoprefixer" +run "#{bundler_cmd} add postcss postcss-cli postcss-import postcss-nesting autoprefixer" say "Add build:css script" -build_script = "postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css" - -case `npx -v`.to_f -when 7.1...8.0 - run %(npm set-script build:css "#{build_script}") - run %(yarn build:css) -when (8.0..) - run %(npm pkg set scripts.build:css="#{build_script}") - run %(yarn build:css) -else - say %(Add "scripts": { "build:css": "#{build_script}" } to your package.json), :green -end +add_package_json_script "build:css", + "postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css" diff --git a/lib/install/sass/install.rb b/lib/install/sass/install.rb index dbdb4c5..692d60e 100644 --- a/lib/install/sass/install.rb +++ b/lib/install/sass/install.rb @@ -1,17 +1,10 @@ +require_relative "../helpers" +self.extend Helpers + say "Install Sass" copy_file "#{__dir__}/application.sass.scss", "app/assets/stylesheets/application.sass.scss" -run "yarn add sass" +run "#{bundler_cmd} add sass" say "Add build:css script" -build_script = "sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" - -case `npx -v`.to_f -when 7.1...8.0 - run %(npm set-script build:css "#{build_script}") - run %(yarn build:css) -when (8.0..) - run %(npm pkg set scripts.build:css="#{build_script}") - run %(yarn build:css) -else - say %(Add "scripts": { "build:css": "#{build_script}" } to your package.json), :green -end +add_package_json_script "build:css", + "sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" diff --git a/lib/install/tailwind/install.rb b/lib/install/tailwind/install.rb index bc7dfcc..7374ff4 100644 --- a/lib/install/tailwind/install.rb +++ b/lib/install/tailwind/install.rb @@ -1,18 +1,11 @@ +require_relative "../helpers" +self.extend Helpers + say "Install Tailwind (+PostCSS w/ autoprefixer)" copy_file "#{__dir__}/tailwind.config.js", "tailwind.config.js" copy_file "#{__dir__}/application.tailwind.css", "app/assets/stylesheets/application.tailwind.css" -run "yarn add tailwindcss@latest postcss@latest autoprefixer@latest" +run "#{bundler_cmd} add tailwindcss@latest postcss@latest autoprefixer@latest" say "Add build:css script" -build_script = "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify" - -case `npx -v`.to_f -when 7.1...8.0 - run %(npm set-script build:css "#{build_script}") - run %(yarn build:css) -when (8.0..) - run %(npm pkg set scripts.build:css="#{build_script}") - run %(yarn build:css) -else - say %(Add "scripts": { "build:css": "#{build_script}" } to your package.json), :green -end +add_package_json_script "build:css", + "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify" diff --git a/lib/tasks/cssbundling/build.rake b/lib/tasks/cssbundling/build.rake index b26335a..90033e2 100644 --- a/lib/tasks/cssbundling/build.rake +++ b/lib/tasks/cssbundling/build.rake @@ -1,18 +1,36 @@ namespace :css do desc "Install JavaScript dependencies" task :install do - unless system "yarn install" - raise "cssbundling-rails: Command install failed, ensure yarn is installed" + command = install_command + unless system(command) + raise "cssbundling-rails: Command install failed, ensure #{command.split.first} is installed" end end desc "Build your CSS bundle" build_task = task :build do - unless system "yarn build:css" - raise "cssbundling-rails: Command css:build failed, ensure yarn is installed and `yarn build:css` runs without errors or use SKIP_CSS_BUILD env variable" + command = build_command + unless system(command) + raise "cssbundling-rails: Command build failed, ensure `#{command}` runs without errors" end end - build_task.prereqs << :install unless ENV["SKIP_YARN_INSTALL"] + build_task.prereqs << :install unless ENV["SKIP_YARN_INSTALL"] || ENV["SKIP_BUN_INSTALL"] +end + +def install_command + return "bun install" if File.exist?('bun.lockb') || (tool_exists?('bun') && !File.exist?('yarn.lock')) + return "yarn install" if File.exist?('yarn.lock') || tool_exists?('yarn') + raise "cssbundling-rails: No suitable tool found for installing JavaScript dependencies" +end + +def build_command + return "bun run build:css" if File.exist?('bun.lockb') || (tool_exists?('bun') && !File.exist?('yarn.lock')) + return "yarn build:css" if File.exist?('yarn.lock') || tool_exists?('yarn') + raise "cssbundling-rails: No suitable tool found for building CSS" +end + +def tool_exists?(tool) + system "command -v #{tool} > /dev/null" end unless ENV["SKIP_CSS_BUILD"]