diff --git a/README.md b/README.md index db1a12cd..75e2dded 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,11 @@ If you want unminified assets, you can pass a `debug` argument to the rake task, Note that you can combine task options, e.g. `rails tailwindcss:watch[debug,poll]`. +### Multiple CSS files + +If you have a reason to break up your CSS into multiple CSS files (for example application.tailwind.css and admin.tailwind.css), as long as your files match the `*.tailwind.css` convention, then the build and watch tasks will create build files with the `tailwind.` removed. + + ### Custom inputs or outputs If you need to use a custom input or output file, you can run `bundle exec tailwindcss` to access the platform-specific executable, and give it your own build options. diff --git a/lib/tailwindcss/commands.rb b/lib/tailwindcss/commands.rb index 4c91428c..d0630bf6 100644 --- a/lib/tailwindcss/commands.rb +++ b/lib/tailwindcss/commands.rb @@ -73,6 +73,29 @@ def watch_command(poll: false, **kwargs) end end + def compile_file_command(file:, debug: false, **kwargs) + file = Pathname.new(file.to_s) + input = file + output = Rails.root.join("app/assets/builds", file.basename.sub("tailwind.", "")) + config = input.open(&:readline).start_with?("@config") ? nil : Rails.root.join("config/tailwind.config.js") + [ + executable(**kwargs), + "-i", input.to_s, + "-o", output.to_s + ].tap do |command| + command << "-c" if config + command << config.to_s if config + command << "--minify" unless debug + end + end + + def watch_file_command(poll: false, **kwargs) + compile_file_command(**kwargs).tap do |command| + command << "-w" + command << "-p" if poll + end + end + def rails_css_compressor? defined?(Rails) && Rails&.application&.config&.assets&.css_compressor.present? end diff --git a/lib/tasks/build.rake b/lib/tasks/build.rake index 27653811..e2cd2b79 100644 --- a/lib/tasks/build.rake +++ b/lib/tasks/build.rake @@ -2,18 +2,46 @@ namespace :tailwindcss do desc "Build your Tailwind CSS" task build: :environment do |_, args| debug = args.extras.include?("debug") - command = Tailwindcss::Commands.compile_command(debug: debug) - puts command.inspect if args.extras.include?("verbose") - system(*command, exception: true) + + files = Rails.root.join("app/assets/stylesheets").glob("*.tailwind.css") + + if files.count == 1 && files.first.basename == "application.tailwind.css" + command = Tailwindcss::Commands.compile_command(debug: debug) + puts command.join(" ") + system(*command, exception: true) + else + files.map do |file| + Tailwindcss::Commands.compile_file_command(file: file, debug: debug) + end.each do |command| + puts command.join(" ") + system(*command, exception: true) + end + end end desc "Watch and build your Tailwind CSS on file changes" task watch: :environment do |_, args| debug = args.extras.include?("debug") poll = args.extras.include?("poll") - command = Tailwindcss::Commands.watch_command(debug: debug, poll: poll) - puts command.inspect if args.extras.include?("verbose") - system(*command) + + files = Rails.root.join("app/assets/stylesheets").glob("*.tailwind.css") + + if files.count == 1 && files.first.basename == "application.tailwind.css" + command = Tailwindcss::Commands.watch_command(debug: debug, poll: poll) + puts command.join(" ") + system(*command) + else + trap("SIGINT") { exit } + + files.map do |file| + Tailwindcss::Commands.watch_file_command(file: file, debug: debug, poll: poll) + end.each do |command| + fork do + puts command.join(" ") + system(*command) + end + end + end end end diff --git a/test/fixtures/application.tailwind.css b/test/fixtures/application.tailwind.css new file mode 100644 index 00000000..b5c61c95 --- /dev/null +++ b/test/fixtures/application.tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/test/fixtures/custom.tailwind.css b/test/fixtures/custom.tailwind.css new file mode 100644 index 00000000..19e4eeb8 --- /dev/null +++ b/test/fixtures/custom.tailwind.css @@ -0,0 +1,4 @@ +@config "custom.tailwind.config.js"; +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/test/lib/tailwindcss/commands_test.rb b/test/lib/tailwindcss/commands_test.rb index ac8f9d05..33150d99 100644 --- a/test/lib/tailwindcss/commands_test.rb +++ b/test/lib/tailwindcss/commands_test.rb @@ -76,6 +76,39 @@ def mock_exe_directory(platform) end end + + test ".compile_file_command" do + mock_exe_directory("sparc-solaris2.8") do |dir, executable| + Rails.stub(:root, Pathname.new(File.dirname(__FILE__))) do + file = Rails.root.join("../../fixtures/application.tailwind.css") + actual = Tailwindcss::Commands.compile_file_command(file: file, exe_path: dir) + assert_kind_of(Array, actual) + assert_equal(executable, actual.first) + assert_includes(actual, "--minify") + assert_includes(actual, "-c") + assert_includes(actual[2], "application.tailwind.css") + refute_includes(actual[4], "tailwind.css") + + actual = Tailwindcss::Commands.compile_file_command(file: file, exe_path: dir, debug: true) + assert_kind_of(Array, actual) + assert_equal(executable, actual.first) + assert_includes(actual, "-c") + refute_includes(actual, "--minify") + assert_includes(actual[2], "application.tailwind.css") + refute_includes(actual[4], "tailwind.css") + + file = Rails.root.join("../../fixtures/custom.tailwind.css") + actual = Tailwindcss::Commands.compile_file_command(file: file, exe_path: dir) + assert_kind_of(Array, actual) + assert_equal(executable, actual.first) + assert_includes(actual, "--minify") + assert_includes(actual[2], "custom.tailwind.css") + refute_includes(actual, "-c") + refute_includes(actual[4], "tailwind.css") + 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 @@ -102,4 +135,42 @@ def mock_exe_directory(platform) end end end + + test ".watch_file_command" do + mock_exe_directory("sparc-solaris2.8") do |dir, executable| + Rails.stub(:root, Pathname.new(File.dirname(__FILE__))) do + file = Rails.root.join("../../fixtures/application.tailwind.css") + actual = Tailwindcss::Commands.watch_file_command(file: file, exe_path: dir) + assert_kind_of(Array, actual) + assert_equal(executable, actual.first) + assert_includes(actual, "-w") + assert_includes(actual, "--minify") + assert_includes(actual, "-c") + assert_includes(actual[2], "application.tailwind.css") + refute_includes(actual, "-p") + refute_includes(actual[4], "tailwind.css") + + actual = Tailwindcss::Commands.watch_file_command(file: file, exe_path: dir, debug: true) + assert_kind_of(Array, actual) + assert_equal(executable, actual.first) + assert_includes(actual, "-w") + assert_includes(actual, "-c") + assert_includes(actual[2], "application.tailwind.css") + refute_includes(actual, "-p") + refute_includes(actual, "--minify") + refute_includes(actual[4], "tailwind.css") + + file = Rails.root.join("../../fixtures/custom.tailwind.css") + actual = Tailwindcss::Commands.watch_file_command(file: file, exe_path: dir, poll: true) + assert_kind_of(Array, actual) + assert_equal(executable, actual.first) + assert_includes(actual, "-w") + assert_includes(actual, "-p") + assert_includes(actual, "--minify") + assert_includes(actual[2], "custom.tailwind.css") + refute_includes(actual, "-c") + refute_includes(actual[4], "tailwind.css") + end + end + end end