Skip to content

rake task execution: test coverage and refactoring #197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 3, 2022
Merged
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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ jobs:

- name: Run tests
run: bin/test

user-journey:
strategy:
fail-fast: false
matrix:
plat: ["ubuntu", "windows", "macos"]
runs-on: ${{matrix.plat}}-latest
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.1"
bundler-cache: true
bundler: latest
- run: test/integration/user_journey_test.sh
shell: bash
55 changes: 14 additions & 41 deletions exe/tailwindcss
Original file line number Diff line number Diff line change
@@ -1,46 +1,19 @@
#! /usr/bin/env ruby
# because rubygems shims assume a gem's executables are Ruby

require "shellwords"
require "tailwindcss/upstream"

supported_platforms = Tailwindcss::Upstream::NATIVE_PLATFORMS.keys
platform = [:cpu, :os].map { |m| Gem::Platform.local.send(m) }.join("-")

if supported_platforms.none? { |supported_platform| Gem::Platform.match(supported_platform) }
STDERR.puts(<<~ERRMSG)
ERROR: tailwindcss-rails does not support the #{platform} platform
Please install tailwindcss following instructions at https://tailwindcss.com/docs/installation
ERRMSG
require "tailwindcss/commands"

begin
command = [Tailwindcss::Commands.executable, *ARGV]
puts command.inspect
if Gem.win_platform?
# use system rather than exec as exec inexplicably fails to find the executable on Windows
# see related https://github.com/rubys/sprockets-esbuild/pull/4
system(*command, exception: true)
else
exec(*command)
end
rescue Tailwindcss::Commands::UnsupportedPlatformException, Tailwindcss::Commands::ExecutableNotFoundException => e
STDERR.puts("ERROR: " + e.message)
exit 1
end

exe_path = Dir.glob(File.join(__dir__, "*", "tailwindcss")).find do |f|
Gem::Platform.match(File.basename(File.dirname(f)))
end
if exe_path.nil?
STDERR.puts(<<~ERRMSG)
ERROR: Cannot find the tailwindcss executable for #{platform} in #{__dir__}
If you're using bundler, please make sure you're on the latest bundler version:

gem install bundler
bundle update --bundler

Then make sure your lock file includes this platform by running:

bundle lock --add-platform #{platform}
bundle install

See `bundle lock --help` output for details.

If you're still seeing this message after taking those steps, try running
`bundle config` and ensure `force_ruby_platform` isn't set to `true`. See
https://github.com/rails/tailwindcss-rails#check-bundle_force_ruby_platform
for more details.
ERRMSG
exit 1
end

command = Shellwords.join([exe_path, ARGV].flatten)
puts "+ #{command}"
exec(command)
7 changes: 4 additions & 3 deletions lib/tailwindcss-rails.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Tailwindcss
end

require "tailwindcss/upstream"
require "tailwindcss/version"
require "tailwindcss/engine"
require_relative "tailwindcss/upstream"
require_relative "tailwindcss/version"
require_relative "tailwindcss/engine"
require_relative "tailwindcss/commands"
73 changes: 73 additions & 0 deletions lib/tailwindcss/commands.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require_relative "upstream"

module Tailwindcss
module Commands
# raised when the host platform is not supported by upstream tailwindcss's binary releases
class UnsupportedPlatformException < StandardError
end

# raised when the tailwindcss executable could not be found where we expected it to be
class ExecutableNotFoundException < StandardError
end

class << self
def platform
[:cpu, :os].map { |m| Gem::Platform.local.send(m) }.join("-")
end

def executable(
exe_path: File.expand_path(File.join(__dir__, "..", "..", "exe"))
)
if Tailwindcss::Upstream::NATIVE_PLATFORMS.keys.none? { |p| Gem::Platform.match(p) }
raise UnsupportedPlatformException, <<~MESSAGE
tailwindcss-rails does not support the #{platform} platform
Please install tailwindcss following instructions at https://tailwindcss.com/docs/installation
MESSAGE
end

exe_path = Dir.glob(File.expand_path(File.join(exe_path, "*", "tailwindcss"))).find do |f|
Gem::Platform.match(File.basename(File.dirname(f)))
end

if exe_path.nil?
raise ExecutableNotFoundException, <<~MESSAGE
Cannot find the tailwindcss executable for #{platform} in #{exe_path}

If you're using bundler, please make sure you're on the latest bundler version:

gem install bundler
bundle update --bundler

Then make sure your lock file includes this platform by running:

bundle lock --add-platform #{platform}
bundle install

See `bundle lock --help` output for details.

If you're still seeing this message after taking those steps, try running
`bundle config` and ensure `force_ruby_platform` isn't set to `true`. See
https://github.com/rails/tailwindcss-rails#check-bundle_force_ruby_platform
for more details.
MESSAGE
end

exe_path
end

def compile_command(**kwargs)
[
executable(**kwargs),
"-i", Rails.root.join("app/assets/stylesheets/application.tailwind.css").to_s,
"-o", Rails.root.join("app/assets/builds/tailwind.css").to_s,
"-c", Rails.root.join("config/tailwind.config.js").to_s,
"--minify",
]
end

def watch_command(**kwargs)
compile_command(**kwargs) << "-w"
end
end
end
end
10 changes: 6 additions & 4 deletions lib/tasks/build.rake
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
TAILWIND_COMPILE_COMMAND = "#{RbConfig.ruby} #{Pathname.new(__dir__).to_s}/../../exe/tailwindcss -i '#{Rails.root.join("app/assets/stylesheets/application.tailwind.css")}' -o '#{Rails.root.join("app/assets/builds/tailwind.css")}' -c '#{Rails.root.join("config/tailwind.config.js")}' --minify"

namespace :tailwindcss do
desc "Build your Tailwind CSS"
task :build do
system(TAILWIND_COMPILE_COMMAND, exception: true)
command = Tailwindcss::Commands.compile_command
puts command.inspect
system(*command, exception: true)
end

desc "Watch and build your Tailwind CSS on file changes"
task :watch do
system "#{TAILWIND_COMPILE_COMMAND} -w"
command = Tailwindcss::Commands.watch_command
puts command.inspect
system(*command)
end
end

Expand Down
27 changes: 27 additions & 0 deletions test/integration/user_journey_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#! /usr/bin/env bash
# reproduce the documented user journey for installing and running tailwindcss-rails
# this is run in the CI pipeline, non-zero exit code indicates a failure

set -o pipefail
set -eux

# fetch the upstream executables
bundle exec rake download

# create a rails app in a directory with spaces in the name (#176, #184)
rm -rf "Has A Space"
mkdir "Has A Space"
pushd "Has A Space"

gem install rails
rails new test-app --skip-bundle
pushd test-app

# install tailwindcss-rails
echo 'gem "tailwindcss-rails", path: "../.."' >> Gemfile
bundle install

bin/rails tailwindcss:install

# ensure rake tasks don't exec (#188)
bin/rails tailwindcss:build about | grep "About your application"
65 changes: 65 additions & 0 deletions test/lib/tailwindcss/commands_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
require "test_helper"
require "minitest/mock"

class Tailwindcss::CommandsTest < ActiveSupport::TestCase
test ".platform is a string containing just the cpu and os (not the version)" do
expected = "#{Gem::Platform.local.cpu}-#{Gem::Platform.local.os}"
assert_equal(expected, Tailwindcss::Commands.platform)
end

def mock_exe_directory(platform)
Dir.mktmpdir do |dir|
FileUtils.mkdir(File.join(dir, platform))
path = File.join(dir, platform, "tailwindcss")
FileUtils.touch(path)
Gem::Platform.stub(:match, true) do
yield(dir, path)
end
end
end

test ".executable returns the absolute path to the binary" do
mock_exe_directory("sparc-solaris2.8") do |dir, executable|
expected = File.expand_path(File.join(dir, "sparc-solaris2.8", "tailwindcss"))
assert_equal(expected, executable, "assert on setup")
assert_equal(expected, Tailwindcss::Commands.executable(exe_path: dir))
end
end

test ".executable raises UnsupportedPlatformException when we're not on a supported platform" do
Gem::Platform.stub(:match, false) do # nothing is supported
assert_raises(Tailwindcss::Commands::UnsupportedPlatformException) do
Tailwindcss::Commands.executable
end
end
end

test ".executable raises ExecutableNotFoundException when we can't find the executable we expect" do
Dir.mktmpdir do |dir| # empty directory
assert_raises(Tailwindcss::Commands::ExecutableNotFoundException) do
Tailwindcss::Commands.executable(exe_path: dir)
end
end
end

test ".compile_command" do
mock_exe_directory("sparc-solaris2.8") do |dir, executable|
Rails.stub(:root, File) do # Rails.root won't work in this test suite
actual = Tailwindcss::Commands.compile_command(exe_path: dir)
assert_kind_of(Array, actual)
assert_equal(executable, actual.first)
end
end
end

test ".watch_command" do
mock_exe_directory("sparc-solaris2.8") do |dir, executable|
Rails.stub(:root, File) do # Rails.root won't work in this test suite
actual = Tailwindcss::Commands.watch_command(exe_path: dir)
assert_kind_of(Array, actual)
assert_equal(executable, actual.first)
assert_includes(actual, "-w")
end
end
end
end