tail_merge 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 163e2f04ba6092bb1d8a0e268dab58a087c9f853edc52ba1ae091cc6b2c7ece4
4
- data.tar.gz: e0aa6a361b8e4219a783b6a00b099ca8dfe6b8c82ae071b2cac8ea4f79d268ce
3
+ metadata.gz: 985f2af19d062ebfae47c4722f5683a2faa1137adc9b29e47c1feafbf8e59f59
4
+ data.tar.gz: 626e7f6b2ea9e7e295e1e32ff7fc080c8d8367d9c796fe17a9f002c798acf804
5
5
  SHA512:
6
- metadata.gz: f5071ee3b5bccf88d692a1863e2d7f4a1c37fd00f13786dd685127a557b5c23f064ece27f8e99f2719aae2e989b52ff09c1cc2395fc7977ceb2a8f7e1704193d
7
- data.tar.gz: 8debb6513dc3035e7acab2ee0ebd58cb4ff265d523c28a17dc77d64fb7930faa02c91c8371875307525c6c63b50080d86f0c1ef20679be7a73077b2d6b76716d
6
+ metadata.gz: 880eaf1b6a414b07697551d1b72ff22ece6aa4ad4dbef1b6252a1d932ba42719b46fdeeb82e90c9ba1a52b447f3aee5cd0477f2fe7f49bf3ac42c2d6c6abb073
7
+ data.tar.gz: 0fe534e17eb22c8c6e3c6960974301a5a6fa94bd7b8f042fdc7e087daafd337721f6a67ac770499ff979c2ba331b684a48df35db67b08583104bdc55a90856d1
data/.rubocop.yml CHANGED
@@ -6,3 +6,9 @@ Style/StringLiterals:
6
6
 
7
7
  Style/StringLiteralsInInterpolation:
8
8
  EnforcedStyle: double_quotes
9
+
10
+ Metrics/BlockLength:
11
+ Enabled: false
12
+
13
+ Layout/LineLength:
14
+ Enabled: false
data/Cargo.lock CHANGED
@@ -114,9 +114,9 @@ dependencies = [
114
114
 
115
115
  [[package]]
116
116
  name = "magnus"
117
- version = "0.6.4"
117
+ version = "0.7.1"
118
118
  source = "registry+https://github.com/rust-lang/crates.io-index"
119
- checksum = "b1597ef40aa8c36be098249e82c9a20cf7199278ac1c1a1a995eeead6a184479"
119
+ checksum = "3d87ae53030f3a22e83879e666cb94e58a7bdf31706878a0ba48752994146dab"
120
120
  dependencies = [
121
121
  "magnus-macros",
122
122
  "rb-sys",
@@ -146,6 +146,7 @@ name = "merger"
146
146
  version = "0.1.0"
147
147
  dependencies = [
148
148
  "magnus",
149
+ "rb-sys",
149
150
  "rustui_merge",
150
151
  ]
151
152
 
data/Rakefile CHANGED
@@ -5,9 +5,12 @@ require "minitest/test_task"
5
5
 
6
6
  Minitest::TestTask.create
7
7
 
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
8
+ begin
9
+ require "rubocop/rake_task"
10
+ RuboCop::RakeTask.new
11
+ rescue LoadError
12
+ # RuboCop is an optional dev dependency; skip in minimal build environments
13
+ end
11
14
 
12
15
  require "rb_sys/extensiontask"
13
16
 
@@ -15,8 +18,52 @@ task build: :compile
15
18
 
16
19
  GEMSPEC = Gem::Specification.load("tail_merge.gemspec")
17
20
 
21
+ # Limit cross-compiled Ruby versions to those supported by this gem and dependencies
22
+ # Format matches rake-compiler's RUBY_CC_VERSION (colon-separated list)
23
+ ENV["RUBY_CC_VERSION"] ||= "3.1.6:3.2.6:3.3.7:3.4.1"
24
+
25
+ PLATFORMS = %w[
26
+ aarch64-linux-gnu
27
+ aarch64-linux-musl
28
+ arm-linux-gnu
29
+ arm-linux-musl
30
+ arm64-darwin
31
+ x64-mingw-ucrt
32
+ x64-mingw32
33
+ x86-linux-gnu
34
+ x86-linux-musl
35
+ x86-mingw32
36
+ x86_64-darwin
37
+ x86_64-linux-gnu
38
+ x86_64-linux-musl
39
+ ].freeze
40
+
18
41
  RbSys::ExtensionTask.new("merger", GEMSPEC) do |ext|
19
42
  ext.lib_dir = "lib/tail_merge"
43
+ ext.cross_compile = true
44
+ ext.cross_platform = %w[x86-mingw32 x64-mingw-ucrt x64-mingw32 x86-linux x86_64-linux aarch64-linux x86_64-darwin arm64-darwin]
45
+ end
46
+
47
+ desc "Build native extension for a given platform (i.e. `rake 'native[x86_64-linux]'`)"
48
+ task :native, [:platform] do |_t, platform:|
49
+ raise ArgumentError, "platform is required, e.g. rake 'native[x86_64-linux]'" if platform.nil? || platform.empty?
50
+
51
+ if platform.end_with?("-darwin")
52
+ # On macOS runners, prefer the native rake task (no Docker available)
53
+ # Map generic arm64-darwin/x86_64-darwin to specific host suffix (e.g. arm64-darwin23)
54
+ require "rbconfig"
55
+ ruby_platform = RUBY_PLATFORM # e.g. "arm64-darwin23"
56
+ darwin_suffix = ruby_platform[/darwin\d+/, 0]
57
+ mapped = platform
58
+ if darwin_suffix && platform =~ /^(arm64|x86_64)-darwin$/
59
+ arch = platform.split("-").first
60
+ mapped = "#{arch}-#{darwin_suffix}"
61
+ end
62
+ sh "bundle", "exec", "rake", "native:#{mapped}", "gem"
63
+ else
64
+ # For Linux/Windows, use Docker-based cross compilation
65
+ sh "bundle", "exec", "rb-sys-dock", "--platform", platform, "--build"
66
+ end
20
67
  end
21
68
 
22
69
  task default: %i[compile test rubocop]
@@ -10,12 +10,12 @@ samples = [
10
10
  ["relative"],
11
11
  ["self-center"],
12
12
  ["self-start"],
13
- ["shadow-inner", "size-4", "text-xs"],
14
- ["shadow-inner", "size-7"],
13
+ %w[shadow-inner size-4 text-xs],
14
+ %w[shadow-inner size-7],
15
15
  ["size-10"],
16
16
  ["static"],
17
17
  ["upload-attachment", "flex-none", "rounded-3xl", "min-h-16", "group", "relative"],
18
- ["w-full", "py-2", "px-2", "rounded-md", "w-44"],
18
+ %w[w-full py-2 px-2 rounded-md w-44],
19
19
  "relative",
20
20
  "self-center",
21
21
  "self-start",
@@ -25,32 +25,48 @@ samples = [
25
25
  "static",
26
26
  "upload-attachment flex-none rounded-3xl min-h-16 group relative",
27
27
  "w-full py-2 px-2 rounded-md w-44",
28
- ["p-4", "px-2", "py-6", "m-3", "mx-8", "my-2", "bg-blue-500", "bg-red-600", "text-sm", "text-lg", "font-bold", "font-normal", "rounded-lg", "rounded-xl", "shadow-md", "shadow-lg", "hover:bg-blue-700", "hover:bg-red-800", "focus:ring-2", "focus:ring-4"],
29
- ["grid", "flex", "inline-flex", "grid-cols-3", "grid-cols-4", "gap-2", "gap-4", "items-center", "items-start", "justify-between", "justify-center", "p-8", "p-4", "bg-gray-100", "bg-white", "border", "border-2", "rounded-full", "rounded-md"],
30
- ["transform", "scale-100", "scale-110", "rotate-45", "rotate-90", "translate-x-2", "translate-x-4", "skew-y-3", "skew-y-6", "transition", "duration-200", "duration-500", "ease-in", "ease-out", "delay-150", "delay-300"],
31
- ["w-full", "w-1/2", "w-3/4", "h-screen", "h-full", "h-32", "min-h-0", "min-h-full", "max-w-xs", "max-w-xl", "overflow-hidden", "overflow-scroll", "object-cover", "object-contain", "opacity-75", "opacity-100"],
32
- ["text-left", "text-center", "text-right", "text-justify", "tracking-wide", "tracking-wider", "leading-tight", "leading-loose", "uppercase", "lowercase", "capitalize", "normal-case", "truncate", "line-clamp-2", "line-clamp-3"],
33
- ["border-t", "border-b", "border-l", "border-r", "border-solid", "border-dashed", "border-red-500", "border-blue-600", "divide-y", "divide-x", "divide-gray-200", "divide-blue-300", "ring-2", "ring-4", "ring-offset-2"],
34
- ["cursor-pointer", "cursor-wait", "select-none", "select-text", "resize", "resize-none", "z-10", "z-50", "float-left", "float-right", "clear-both", "clear-none", "box-border", "box-content"],
35
- ["bg-opacity-50", "bg-opacity-75", "backdrop-blur-sm", "backdrop-blur-lg", "backdrop-filter", "filter", "brightness-90", "brightness-110", "contrast-75", "contrast-125", "saturate-50", "saturate-200"],
36
- ["focus:outline-none", "focus:ring-2", "focus:ring-offset-2", "focus:border-blue-500", "hover:scale-105", "hover:rotate-3", "active:scale-95", "disabled:opacity-50", "disabled:cursor-not-allowed"],
37
- ["sm:text-lg", "md:text-xl", "lg:text-2xl", "xl:text-3xl", "2xl:text-4xl", "sm:w-1/2", "md:w-2/3", "lg:w-3/4", "xl:w-full", "2xl:max-w-screen-xl", "sm:p-4", "md:p-6", "lg:p-8", "xl:p-10"],
38
- ["dark:bg-gray-800", "dark:text-white", "dark:border-gray-600", "dark:hover:bg-gray-700", "dark:focus:ring-blue-800", "bg-white", "text-black", "border-gray-200", "hover:bg-gray-100"],
39
- ["group-hover:scale-110", "group-hover:rotate-6", "group-focus:outline-none", "group-active:scale-95", "peer-checked:bg-blue-500", "peer-checked:text-white", "peer-disabled:opacity-50"],
40
- ["animate-spin", "animate-pulse", "animate-bounce", "animate-ping", "motion-safe:animate-spin", "motion-reduce:animate-none", "transition-all", "duration-300", "ease-in-out", "delay-150"],
41
- ["space-x-4", "space-x-reverse", "space-y-6", "space-y-reverse", "gap-x-4", "gap-y-6", "place-items-center", "place-content-center", "place-self-center", "content-center"],
42
- ["from-blue-500", "to-purple-500", "via-pink-500", "bg-gradient-to-r", "bg-gradient-to-br", "text-transparent", "bg-clip-text", "bg-origin-border", "bg-no-repeat", "bg-cover"],
43
- ["columns-2", "columns-3", "break-inside-avoid", "break-after-column", "aspect-square", "aspect-video", "object-right-top", "object-left-bottom", "isolation-auto", "mix-blend-multiply"],
44
- ["first:pt-0", "last:pb-0", "odd:bg-gray-50", "even:bg-white", "first-letter:text-7xl", "first-line:uppercase", "selection:bg-yellow-200", "selection:text-black"],
45
- ["[mask-type:luminance]", "[mask-type:alpha]", "[transform-style:preserve-3d]", "[clip-path:circle(50%)]", "[-webkit-text-stroke:2px]", "[text-align-last:justify]"],
46
- ["will-change-scroll", "will-change-transform", "scroll-smooth", "scroll-mt-2", "scroll-pb-4", "overscroll-contain", "touch-pan-right", "touch-manipulation"],
47
- ["hyphens-auto", "hyphens-manual", "text-underline-offset-2", "text-decoration-thickness-2", "indent-8", "indent-16", "vertical-align-sub", "vertical-align-super"]
28
+ ["p-4", "px-2", "py-6", "m-3", "mx-8", "my-2", "bg-blue-500", "bg-red-600", "text-sm", "text-lg", "font-bold",
29
+ "font-normal", "rounded-lg", "rounded-xl", "shadow-md", "shadow-lg", "hover:bg-blue-700", "hover:bg-red-800", "focus:ring-2", "focus:ring-4"],
30
+ %w[grid flex inline-flex grid-cols-3 grid-cols-4 gap-2 gap-4 items-center items-start
31
+ justify-between justify-center p-8 p-4 bg-gray-100 bg-white border border-2 rounded-full rounded-md],
32
+ ["transform", "scale-100", "scale-110", "rotate-45", "rotate-90", "translate-x-2", "translate-x-4", "skew-y-3",
33
+ "skew-y-6", "transition", "duration-200", "duration-500", "ease-in", "ease-out", "delay-150", "delay-300"],
34
+ ["w-full", "w-1/2", "w-3/4", "h-screen", "h-full", "h-32", "min-h-0", "min-h-full", "max-w-xs", "max-w-xl",
35
+ "overflow-hidden", "overflow-scroll", "object-cover", "object-contain", "opacity-75", "opacity-100"],
36
+ %w[text-left text-center text-right text-justify tracking-wide tracking-wider leading-tight
37
+ leading-loose uppercase lowercase capitalize normal-case truncate line-clamp-2 line-clamp-3],
38
+ %w[border-t border-b border-l border-r border-solid border-dashed border-red-500
39
+ border-blue-600 divide-y divide-x divide-gray-200 divide-blue-300 ring-2 ring-4 ring-offset-2],
40
+ %w[cursor-pointer cursor-wait select-none select-text resize resize-none z-10 z-50
41
+ float-left float-right clear-both clear-none box-border box-content],
42
+ %w[bg-opacity-50 bg-opacity-75 backdrop-blur-sm backdrop-blur-lg backdrop-filter filter
43
+ brightness-90 brightness-110 contrast-75 contrast-125 saturate-50 saturate-200],
44
+ ["focus:outline-none", "focus:ring-2", "focus:ring-offset-2", "focus:border-blue-500", "hover:scale-105",
45
+ "hover:rotate-3", "active:scale-95", "disabled:opacity-50", "disabled:cursor-not-allowed"],
46
+ ["sm:text-lg", "md:text-xl", "lg:text-2xl", "xl:text-3xl", "2xl:text-4xl", "sm:w-1/2", "md:w-2/3", "lg:w-3/4",
47
+ "xl:w-full", "2xl:max-w-screen-xl", "sm:p-4", "md:p-6", "lg:p-8", "xl:p-10"],
48
+ ["dark:bg-gray-800", "dark:text-white", "dark:border-gray-600", "dark:hover:bg-gray-700", "dark:focus:ring-blue-800",
49
+ "bg-white", "text-black", "border-gray-200", "hover:bg-gray-100"],
50
+ ["group-hover:scale-110", "group-hover:rotate-6", "group-focus:outline-none", "group-active:scale-95",
51
+ "peer-checked:bg-blue-500", "peer-checked:text-white", "peer-disabled:opacity-50"],
52
+ ["animate-spin", "animate-pulse", "animate-bounce", "animate-ping", "motion-safe:animate-spin",
53
+ "motion-reduce:animate-none", "transition-all", "duration-300", "ease-in-out", "delay-150"],
54
+ ["space-x-4", "space-x-reverse", "space-y-6", "space-y-reverse", "gap-x-4", "gap-y-6", "place-items-center",
55
+ "place-content-center", "place-self-center", "content-center"],
56
+ %w[from-blue-500 to-purple-500 via-pink-500 bg-gradient-to-r bg-gradient-to-br text-transparent
57
+ bg-clip-text bg-origin-border bg-no-repeat bg-cover],
58
+ %w[columns-2 columns-3 break-inside-avoid break-after-column aspect-square aspect-video
59
+ object-right-top object-left-bottom isolation-auto mix-blend-multiply],
60
+ ["first:pt-0", "last:pb-0", "odd:bg-gray-50", "even:bg-white", "first-letter:text-7xl", "first-line:uppercase",
61
+ "selection:bg-yellow-200", "selection:text-black"],
62
+ ["[mask-type:luminance]", "[mask-type:alpha]", "[transform-style:preserve-3d]", "[clip-path:circle(50%)]",
63
+ "[-webkit-text-stroke:2px]", "[text-align-last:justify]"],
64
+ %w[will-change-scroll will-change-transform scroll-smooth scroll-mt-2 scroll-pb-4 overscroll-contain
65
+ touch-pan-right touch-manipulation],
66
+ %w[hyphens-auto hyphens-manual text-underline-offset-2 text-decoration-thickness-2 indent-8 indent-16
67
+ vertical-align-sub vertical-align-super]
48
68
  ]
49
69
 
50
- require 'benchmark'
51
- require 'tail_merge'
52
- require 'tailwind_merge'
53
-
54
70
  # Pre-initialize cached mergers
55
71
  cached_merger = TailwindMerge::Merger.new
56
72
 
@@ -10,5 +10,6 @@ name = "merger"
10
10
  crate-type = ["cdylib"]
11
11
 
12
12
  [dependencies]
13
- magnus = { version = "0.6.2" }
13
+ magnus = "0.7.1"
14
14
  rustui_merge = "0.1.6"
15
+ rb-sys = "0.9.115"
@@ -1,5 +1,5 @@
1
1
  use magnus::{
2
- define_module, function, prelude::*, Error, RArray, RHash, RString, Ruby, Value,
2
+ function, prelude::*, Error, RArray, RHash, RString, Ruby, Value,
3
3
  };
4
4
  use rustui_merge::merge::tw_merge;
5
5
 
@@ -14,13 +14,13 @@ fn merge_tailwind_classes(args: &[Value]) -> Result<RString, Error> {
14
14
 
15
15
  // ---------- 2. collect class tokens ------------------------------------
16
16
  let mut tokens = Vec::<String>::new();
17
- let is_string_input = matches!(args[0].clone().try_convert::<RString>(), Ok(_));
18
- match args[0].clone().try_convert::<RString>() {
17
+ let is_string_input = matches!(RString::try_convert(args[0].clone()), Ok(_));
18
+ match RString::try_convert(args[0].clone()) {
19
19
  Ok(rstr) => tokens.extend(rstr.to_string()?.split_whitespace().map(str::to_owned)),
20
20
  Err(_) => {
21
- let rarray: RArray = args[0].try_convert()?;
22
- for v in rarray.each() {
23
- let s: RString = v?.try_convert()?;
21
+ let rarray: RArray = RArray::try_convert(args[0])?;
22
+ for v in rarray.into_iter() {
23
+ let s: RString = RString::try_convert(v)?;
24
24
  tokens.push(s.to_string()?);
25
25
  }
26
26
  }
@@ -28,7 +28,7 @@ fn merge_tailwind_classes(args: &[Value]) -> Result<RString, Error> {
28
28
 
29
29
  // Early returns for simple cases
30
30
  if is_string_input {
31
- let rstr: RString = args[0].clone().try_convert()?;
31
+ let rstr: RString = RString::try_convert(args[0].clone())?;
32
32
  let s = rstr.to_string()?;
33
33
  if !s.contains(' ') {
34
34
  // Single class string, return as-is
@@ -49,15 +49,15 @@ fn merge_tailwind_classes(args: &[Value]) -> Result<RString, Error> {
49
49
  let mut separator: Option<String> = None;
50
50
 
51
51
  if args.len() == 2 {
52
- let rhash: RHash = args[1].try_convert()?;
52
+ let rhash: RHash = RHash::try_convert(args[1])?;
53
53
  let ruby = Ruby::get().unwrap();
54
54
 
55
55
  if let Some(v) = rhash.get(ruby.to_symbol("prefix")) {
56
- let s: RString = v.try_convert()?;
56
+ let s: RString = RString::try_convert(v)?;
57
57
  prefix = Some(s.to_string()?);
58
58
  }
59
59
  if let Some(v) = rhash.get(ruby.to_symbol("separator")) {
60
- let s: RString = v.try_convert()?;
60
+ let s: RString = RString::try_convert(v)?;
61
61
  separator = Some(s.to_string()?);
62
62
  }
63
63
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TailMerge
4
- VERSION = "0.4.1"
4
+ VERSION = "0.4.3"
5
5
  end
data/lib/tail_merge.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "tail_merge/version"
4
- require_relative "tail_merge/merger"
4
+ require "tail_merge/merger"
5
5
 
6
6
  # Main class for merging tailwind classes.
7
7
  class TailMerge
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tail_merge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Achilleas Buisman
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2025-08-21 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: rb_sys
@@ -15,14 +16,14 @@ dependencies:
15
16
  requirements:
16
17
  - - "~>"
17
18
  - !ruby/object:Gem::Version
18
- version: 0.9.91
19
+ version: 0.9.115
19
20
  type: :runtime
20
21
  prerelease: false
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
24
  - - "~>"
24
25
  - !ruby/object:Gem::Version
25
- version: 0.9.91
26
+ version: 0.9.115
26
27
  description: Merge Tailwind CSS classes
27
28
  email:
28
29
  - accounts@abuisman.nl
@@ -44,11 +45,13 @@ files:
44
45
  - lib/tail_merge/version.rb
45
46
  - sig/tail_merge.rbs
46
47
  homepage: https://github.com/abuisman/tail_merge
47
- licenses: []
48
+ licenses:
49
+ - MIT
48
50
  metadata:
49
51
  allowed_push_host: https://rubygems.org
50
52
  homepage_uri: https://github.com/abuisman/tail_merge
51
53
  source_code_uri: https://github.com/abuisman/tail_merge
54
+ post_install_message:
52
55
  rdoc_options: []
53
56
  require_paths:
54
57
  - lib
@@ -63,7 +66,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
66
  - !ruby/object:Gem::Version
64
67
  version: 3.3.11
65
68
  requirements: []
66
- rubygems_version: 3.6.9
69
+ rubygems_version: 3.5.22
70
+ signing_key:
67
71
  specification_version: 4
68
72
  summary: Merge Tailwind CSS classes
69
73
  test_files: []