shadcn-rails 0.2.0 → 0.2.1

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.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -2
  3. data/README.md +21 -8
  4. data/__mocks__/@floating-ui/dom.js +67 -0
  5. data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +23 -2
  6. data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +4 -31
  7. data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +32 -41
  8. data/app/assets/javascripts/shadcn/controllers/hover_card_controller.js +29 -55
  9. data/app/assets/javascripts/shadcn/controllers/popover_controller.js +29 -54
  10. data/app/assets/javascripts/shadcn/controllers/select_controller.js +26 -8
  11. data/app/assets/javascripts/shadcn/controllers/tooltip_controller.js +28 -59
  12. data/app/assets/javascripts/shadcn/index.js +7 -1
  13. data/app/assets/javascripts/shadcn/utils/floating.js +179 -0
  14. data/app/assets/stylesheets/shadcn/base.css +32 -0
  15. data/app/components/shadcn/accordion_component.html.erb +8 -0
  16. data/app/components/shadcn/accordion_component.rb +6 -15
  17. data/app/components/shadcn/alert_component.html.erb +6 -0
  18. data/app/components/shadcn/alert_component.rb +0 -18
  19. data/app/components/shadcn/alert_dialog_component.html.erb +12 -0
  20. data/app/components/shadcn/alert_dialog_component.rb +7 -27
  21. data/app/components/shadcn/aspect_ratio_component.html.erb +7 -0
  22. data/app/components/shadcn/aspect_ratio_component.rb +4 -19
  23. data/app/components/shadcn/avatar_component.html.erb +20 -0
  24. data/app/components/shadcn/avatar_component.rb +8 -36
  25. data/app/components/shadcn/badge_component.html.erb +1 -0
  26. data/app/components/shadcn/badge_component.rb +0 -11
  27. data/app/components/shadcn/base_component.rb +15 -2
  28. data/app/components/shadcn/breadcrumb_component.html.erb +5 -0
  29. data/app/components/shadcn/breadcrumb_component.rb +6 -16
  30. data/app/components/shadcn/button_component.html.erb +18 -0
  31. data/app/components/shadcn/button_component.rb +1 -41
  32. data/app/components/shadcn/card_component.html.erb +8 -0
  33. data/app/components/shadcn/card_component.rb +2 -6
  34. data/app/components/shadcn/checkbox_component.html.erb +32 -0
  35. data/app/components/shadcn/checkbox_component.rb +4 -43
  36. data/app/components/shadcn/collapsible_component.html.erb +8 -0
  37. data/app/components/shadcn/collapsible_component.rb +6 -15
  38. data/app/components/shadcn/context_menu_component.html.erb +11 -0
  39. data/app/components/shadcn/context_menu_component.rb +6 -26
  40. data/app/components/shadcn/dialog_component.html.erb +14 -0
  41. data/app/components/shadcn/dialog_component.rb +8 -29
  42. data/app/components/shadcn/drawer_component.html.erb +12 -0
  43. data/app/components/shadcn/drawer_component.rb +7 -27
  44. data/app/components/shadcn/dropdown_menu_component.html.erb +14 -0
  45. data/app/components/shadcn/dropdown_menu_component.rb +9 -29
  46. data/app/components/shadcn/field_component.rb +7 -8
  47. data/app/components/shadcn/hover_card_component.html.erb +12 -0
  48. data/app/components/shadcn/hover_card_component.rb +7 -26
  49. data/app/components/shadcn/input_component.html.erb +18 -0
  50. data/app/components/shadcn/input_component.rb +2 -27
  51. data/app/components/shadcn/input_otp_component.rb +3 -3
  52. data/app/components/shadcn/kbd_component.html.erb +1 -0
  53. data/app/components/shadcn/kbd_component.rb +3 -10
  54. data/app/components/shadcn/label_component.html.erb +3 -0
  55. data/app/components/shadcn/label_component.rb +2 -18
  56. data/app/components/shadcn/menubar_component.html.erb +6 -0
  57. data/app/components/shadcn/menubar_component.rb +4 -15
  58. data/app/components/shadcn/native_select_component.html.erb +22 -0
  59. data/app/components/shadcn/native_select_component.rb +9 -39
  60. data/app/components/shadcn/navigation_menu_component.html.erb +6 -0
  61. data/app/components/shadcn/navigation_menu_component.rb +4 -15
  62. data/app/components/shadcn/pagination_component.html.erb +5 -0
  63. data/app/components/shadcn/pagination_component.rb +11 -15
  64. data/app/components/shadcn/popover_component.html.erb +15 -0
  65. data/app/components/shadcn/popover_component.rb +10 -30
  66. data/app/components/shadcn/progress_component.html.erb +13 -0
  67. data/app/components/shadcn/progress_component.rb +6 -26
  68. data/app/components/shadcn/radio_group_component.html.erb +8 -0
  69. data/app/components/shadcn/radio_group_component.rb +12 -26
  70. data/app/components/shadcn/scroll_area_component.html.erb +7 -0
  71. data/app/components/shadcn/scroll_area_component.rb +4 -16
  72. data/app/components/shadcn/select_component.html.erb +46 -0
  73. data/app/components/shadcn/select_component.rb +6 -80
  74. data/app/components/shadcn/separator_component.html.erb +5 -0
  75. data/app/components/shadcn/separator_component.rb +6 -14
  76. data/app/components/shadcn/sheet_component.html.erb +12 -0
  77. data/app/components/shadcn/sheet_component.rb +7 -27
  78. data/app/components/shadcn/sidebar_component.rb +2 -2
  79. data/app/components/shadcn/skeleton_component.html.erb +1 -0
  80. data/app/components/shadcn/skeleton_component.rb +4 -2
  81. data/app/components/shadcn/slider_component.html.erb +12 -0
  82. data/app/components/shadcn/slider_component.rb +2 -21
  83. data/app/components/shadcn/spinner_component.html.erb +18 -0
  84. data/app/components/shadcn/spinner_component.rb +2 -30
  85. data/app/components/shadcn/switch_component.html.erb +72 -0
  86. data/app/components/shadcn/switch_component.rb +4 -82
  87. data/app/components/shadcn/table_component.html.erb +9 -0
  88. data/app/components/shadcn/table_component.rb +2 -10
  89. data/app/components/shadcn/tabs_component.html.erb +8 -0
  90. data/app/components/shadcn/tabs_component.rb +4 -17
  91. data/app/components/shadcn/textarea_component.html.erb +13 -0
  92. data/app/components/shadcn/textarea_component.rb +6 -22
  93. data/app/components/shadcn/toast_component.html.erb +36 -0
  94. data/app/components/shadcn/toast_component.rb +6 -54
  95. data/app/components/shadcn/toggle_component.html.erb +12 -0
  96. data/app/components/shadcn/toggle_component.rb +6 -21
  97. data/app/components/shadcn/toggle_group_component.html.erb +14 -0
  98. data/app/components/shadcn/toggle_group_component.rb +6 -29
  99. data/app/components/shadcn/tooltip_component.html.erb +20 -0
  100. data/app/components/shadcn/tooltip_component.rb +13 -38
  101. data/lib/generators/shadcn/add/USAGE +24 -0
  102. data/lib/generators/shadcn/add/add_generator.rb +279 -0
  103. data/lib/generators/shadcn/install/USAGE +22 -0
  104. data/lib/generators/shadcn/install/install_generator.rb +8 -3
  105. data/lib/generators/shadcn/install/templates/initializer.rb.tt +7 -27
  106. data/lib/generators/shadcn/install/templates/shadcn.yml.tt +15 -31
  107. data/lib/shadcn/rails/version.rb +1 -1
  108. metadata +47 -45
  109. data/.dockerignore +0 -40
  110. data/CLAUDE.md +0 -612
  111. data/PROGRESS.md +0 -495
  112. data/Rakefile +0 -95
  113. data/__tests__/controllers/__snapshots__/calendar_controller.test.js.snap +0 -13
  114. data/__tests__/controllers/__snapshots__/popover_controller.test.js.snap +0 -46
  115. data/__tests__/controllers/__snapshots__/sheet_controller.test.js.snap +0 -111
  116. data/__tests__/controllers/__snapshots__/tabs_controller.test.js.snap +0 -27
  117. data/__tests__/controllers/accordion_controller.test.js +0 -904
  118. data/__tests__/controllers/calendar_controller.test.js +0 -1370
  119. data/__tests__/controllers/carousel_controller.test.js +0 -912
  120. data/__tests__/controllers/checkbox_controller.test.js +0 -454
  121. data/__tests__/controllers/collapsible_controller.test.js +0 -407
  122. data/__tests__/controllers/combobox_controller.test.js +0 -971
  123. data/__tests__/controllers/context_menu_controller.test.js +0 -905
  124. data/__tests__/controllers/date_picker_controller.test.js +0 -636
  125. data/__tests__/controllers/dialog_controller.test.js +0 -878
  126. data/__tests__/controllers/drawer_controller.test.js +0 -995
  127. data/__tests__/controllers/menubar_controller.test.js +0 -737
  128. data/__tests__/controllers/navigation_menu_controller.test.js +0 -599
  129. data/__tests__/controllers/popover_controller.test.js +0 -982
  130. data/__tests__/controllers/radio_group_controller.test.js +0 -640
  131. data/__tests__/controllers/resizable_controller.test.js +0 -680
  132. data/__tests__/controllers/select_controller.test.js +0 -678
  133. data/__tests__/controllers/sheet_controller.test.js +0 -986
  134. data/__tests__/controllers/slider_controller.test.js +0 -1036
  135. data/__tests__/controllers/switch_controller.test.js +0 -424
  136. data/__tests__/controllers/tabs_controller.test.js +0 -907
  137. data/__tests__/controllers/toggle_group_controller.test.js +0 -839
  138. data/__tests__/controllers/tooltip_controller.test.js +0 -808
  139. data/__tests__/helpers/stimulus-test-helper.js +0 -203
  140. data/babel.config.cjs +0 -5
  141. data/bin/bump +0 -321
  142. data/bin/console +0 -11
  143. data/bin/release +0 -205
  144. data/bin/setup +0 -8
  145. data/bin/test +0 -75
  146. data/jest.config.js +0 -19
  147. data/jest.setup.js +0 -8
  148. data/lib/generators/shadcn/component/component_generator.rb +0 -188
  149. data/lib/generators/shadcn/theme/theme_generator.rb +0 -128
  150. data/package-lock.json +0 -7438
  151. data/package.json +0 -71
  152. data/rollup.config.js +0 -29
@@ -1,203 +0,0 @@
1
- import { Application } from "@hotwired/stimulus"
2
-
3
- /**
4
- * Helper to set up Stimulus controller tests
5
- * Creates a DOM element with the controller connected
6
- */
7
- export function setupController(Controller, html, controllerName = 'test') {
8
- const application = Application.start()
9
- application.register(controllerName, Controller)
10
-
11
- document.body.innerHTML = html
12
-
13
- // Wait for Stimulus to connect the controller
14
- return new Promise((resolve) => {
15
- requestAnimationFrame(() => {
16
- const element = document.querySelector(`[data-controller="${controllerName}"]`)
17
- const controller = application.getControllerForElementAndIdentifier(element, controllerName)
18
- resolve({ application, element, controller })
19
- })
20
- })
21
- }
22
-
23
- /**
24
- * Clean up after tests
25
- */
26
- export function cleanupController(application) {
27
- if (application) {
28
- application.stop()
29
- }
30
- document.body.innerHTML = ''
31
- }
32
-
33
- /**
34
- * Simulate a click event on an element
35
- */
36
- export function click(element) {
37
- element.dispatchEvent(new MouseEvent('click', {
38
- bubbles: true,
39
- cancelable: true,
40
- view: window
41
- }))
42
- }
43
-
44
- /**
45
- * Wait for a specified number of milliseconds
46
- */
47
- export function wait(ms) {
48
- return new Promise(resolve => setTimeout(resolve, ms))
49
- }
50
-
51
- /**
52
- * Wait for an animation frame
53
- */
54
- export function nextFrame() {
55
- return new Promise(resolve => requestAnimationFrame(resolve))
56
- }
57
-
58
- /**
59
- * Simulate a keyboard event on an element
60
- * @param {Element} element - Target element
61
- * @param {string} key - Key name (e.g., 'ArrowDown', 'Enter', 'Escape')
62
- * @param {Object} options - Additional options (shiftKey, ctrlKey, etc.)
63
- */
64
- export function keydown(element, key, options = {}) {
65
- element.dispatchEvent(new KeyboardEvent('keydown', {
66
- key,
67
- bubbles: true,
68
- cancelable: true,
69
- ...options
70
- }))
71
- }
72
-
73
- /**
74
- * Simulate a keyup event
75
- */
76
- export function keyup(element, key, options = {}) {
77
- element.dispatchEvent(new KeyboardEvent('keyup', {
78
- key,
79
- bubbles: true,
80
- cancelable: true,
81
- ...options
82
- }))
83
- }
84
-
85
- /**
86
- * Wait for a portal element to appear in the DOM
87
- * @param {string} selector - CSS selector for the portal
88
- * @param {boolean} shouldExist - Whether portal should exist (true) or not exist (false)
89
- * @param {number} timeout - Maximum wait time in ms
90
- */
91
- export async function waitForPortal(selector, shouldExist = true, timeout = 1000) {
92
- const startTime = Date.now()
93
-
94
- while (Date.now() - startTime < timeout) {
95
- const element = document.querySelector(selector)
96
- if (shouldExist && element) return element
97
- if (!shouldExist && !element) return null
98
- await wait(10)
99
- }
100
-
101
- throw new Error(`Portal ${selector} ${shouldExist ? 'did not appear' : 'did not disappear'} within ${timeout}ms`)
102
- }
103
-
104
- /**
105
- * Mock window.location for URL-related tests
106
- * Uses jsdom's internal reconfigure or modifies location properties
107
- * @param {string} url - The URL to mock
108
- * @returns {Function} Cleanup function to restore original location
109
- */
110
- export function mockLocation(url) {
111
- // Store original href
112
- const originalHref = window.location.href
113
-
114
- // Use jsdom's reconfigure if available (available in newer jsdom)
115
- if (typeof window._virtualConsole !== 'undefined' && window.location._setHref) {
116
- window.location._setHref(url)
117
- return () => {
118
- if (window.location._setHref) {
119
- window.location._setHref(originalHref)
120
- }
121
- }
122
- }
123
-
124
- // Fallback: Use history API to change URL without navigation
125
- const urlObj = new URL(url, window.location.origin)
126
- window.history.replaceState({}, '', urlObj.href)
127
-
128
- return () => {
129
- window.history.replaceState({}, '', originalHref)
130
- }
131
- }
132
-
133
- /**
134
- * Mock history.pushState and replaceState for URL sync tests
135
- */
136
- export function mockHistory() {
137
- const originalPushState = window.history.pushState
138
- const originalReplaceState = window.history.replaceState
139
-
140
- const calls = {
141
- pushState: [],
142
- replaceState: []
143
- }
144
-
145
- window.history.pushState = (state, title, url) => {
146
- calls.pushState.push({ state, title, url })
147
- }
148
-
149
- window.history.replaceState = (state, title, url) => {
150
- calls.replaceState.push({ state, title, url })
151
- }
152
-
153
- return {
154
- calls,
155
- restore: () => {
156
- window.history.pushState = originalPushState
157
- window.history.replaceState = originalReplaceState
158
- }
159
- }
160
- }
161
-
162
- /**
163
- * Get all focusable elements within a container
164
- * @param {Element} container - Container element
165
- */
166
- export function getFocusableElements(container) {
167
- return container.querySelectorAll(
168
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
169
- )
170
- }
171
-
172
- /**
173
- * Dispatch a custom event
174
- * @param {Element} element - Target element
175
- * @param {string} eventName - Event name
176
- * @param {Object} detail - Event detail object
177
- */
178
- export function dispatchEvent(element, eventName, detail = {}) {
179
- element.dispatchEvent(new CustomEvent(eventName, {
180
- bubbles: true,
181
- cancelable: true,
182
- detail
183
- }))
184
- }
185
-
186
- /**
187
- * Wait for controller to emit a specific event
188
- * @param {Element} element - Element to listen on
189
- * @param {string} eventName - Event name (e.g., 'shadcn--accordion:expand')
190
- * @param {number} timeout - Maximum wait time
191
- */
192
- export function waitForEvent(element, eventName, timeout = 1000) {
193
- return new Promise((resolve, reject) => {
194
- const timer = setTimeout(() => {
195
- reject(new Error(`Event ${eventName} not received within ${timeout}ms`))
196
- }, timeout)
197
-
198
- element.addEventListener(eventName, (event) => {
199
- clearTimeout(timer)
200
- resolve(event)
201
- }, { once: true })
202
- })
203
- }
data/babel.config.cjs DELETED
@@ -1,5 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- ['@babel/preset-env', { targets: { node: 'current' } }]
4
- ]
5
- }
data/bin/bump DELETED
@@ -1,321 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Version bump script for shadcn-rails
5
- # Updates version in both Ruby gem and npm package, commits, and tags
6
- #
7
- # Usage:
8
- # bin/bump patch # Bump patch version, commit, and tag
9
- # bin/bump minor # Bump minor version, commit, and tag
10
- # bin/bump major # Bump major version, commit, and tag
11
- # bin/bump 1.0.0 # Set specific version, commit, and tag
12
- #
13
- # Options:
14
- # --no-commit Only update files, don't commit or tag
15
- # --push Push commits and tags to remote after bumping
16
- # --release Push and publish to RubyGems and npm
17
- # --dry-run Show what would happen without making changes
18
-
19
- require "json"
20
- require "fileutils"
21
- require "optparse"
22
-
23
- VERSION_FILE = File.expand_path("../lib/shadcn/rails/version.rb", __dir__)
24
- PACKAGE_JSON = File.expand_path("../package.json", __dir__)
25
- CHANGELOG_FILE = File.expand_path("../CHANGELOG.md", __dir__)
26
-
27
- class VersionBumper
28
- def initialize(bump_type:, commit: true, push: false, release: false, dry_run: false)
29
- @bump_type = bump_type
30
- @commit = commit
31
- @push = push
32
- @release = release
33
- @dry_run = dry_run
34
- end
35
-
36
- def run
37
- validate_environment
38
-
39
- @old_version = current_version
40
- @new_version = calculate_new_version
41
-
42
- puts "\n📦 Bumping version: #{@old_version} → #{@new_version}\n\n"
43
-
44
- update_files
45
- commit_and_tag if @commit
46
- push_to_remote if @push || @release
47
- publish_packages if @release
48
-
49
- print_summary
50
- end
51
-
52
- private
53
-
54
- def validate_environment
55
- # Check versions are in sync
56
- ruby_ver = current_version
57
- npm_ver = JSON.parse(File.read(PACKAGE_JSON))["version"]
58
-
59
- if ruby_ver != npm_ver
60
- error "Versions are out of sync!\n Ruby: #{ruby_ver}\n npm: #{npm_ver}"
61
- end
62
-
63
- # Check for clean working directory if we're going to commit
64
- if @commit && !@dry_run
65
- status = `git status --porcelain`.strip
66
- unless status.empty?
67
- error "Working directory is not clean. Commit or stash changes first.\n\n#{status}"
68
- end
69
- end
70
-
71
- # Check we're on a reasonable branch for releasing
72
- if @release && !@dry_run
73
- branch = `git branch --show-current`.strip
74
- unless %w[main master].include?(branch)
75
- puts "⚠️ Warning: You're on branch '#{branch}', not main/master"
76
- print "Continue anyway? [y/N] "
77
- response = $stdin.gets&.strip&.downcase
78
- exit 1 unless response == "y"
79
- end
80
- end
81
- end
82
-
83
- def current_version
84
- content = File.read(VERSION_FILE)
85
- content.match(/VERSION = "(.+?)"/)[1]
86
- end
87
-
88
- def calculate_new_version
89
- major, minor, patch = @old_version.split(".").map(&:to_i)
90
-
91
- case @bump_type
92
- when "major"
93
- "#{major + 1}.0.0"
94
- when "minor"
95
- "#{major}.#{minor + 1}.0"
96
- when "patch"
97
- "#{major}.#{minor}.#{patch + 1}"
98
- when /^\d+\.\d+\.\d+$/
99
- @bump_type
100
- else
101
- error "Invalid version type: #{@bump_type}\nUse: patch, minor, major, or X.Y.Z"
102
- end
103
- end
104
-
105
- def update_files
106
- step "Updating version files"
107
-
108
- # Update Ruby version
109
- if @dry_run
110
- puts " [dry-run] Would update #{VERSION_FILE}"
111
- else
112
- content = File.read(VERSION_FILE)
113
- new_content = content.gsub(/VERSION = ".+?"/, %(VERSION = "#{@new_version}"))
114
- File.write(VERSION_FILE, new_content)
115
- puts " ✓ Updated #{File.basename(VERSION_FILE)}"
116
- end
117
-
118
- # Update npm version
119
- if @dry_run
120
- puts " [dry-run] Would update #{PACKAGE_JSON}"
121
- else
122
- package = JSON.parse(File.read(PACKAGE_JSON))
123
- package["version"] = @new_version
124
- File.write(PACKAGE_JSON, JSON.pretty_generate(package) + "\n")
125
- puts " ✓ Updated #{File.basename(PACKAGE_JSON)}"
126
- end
127
-
128
- # Update changelog
129
- if File.exist?(CHANGELOG_FILE)
130
- if @dry_run
131
- puts " [dry-run] Would update #{CHANGELOG_FILE}"
132
- else
133
- update_changelog
134
- puts " ✓ Updated #{File.basename(CHANGELOG_FILE)}"
135
- end
136
- end
137
- end
138
-
139
- def update_changelog
140
- content = File.read(CHANGELOG_FILE)
141
- today = Time.now.strftime("%Y-%m-%d")
142
-
143
- # Replace [Unreleased] with new version
144
- new_content = content.gsub(
145
- /## \[Unreleased\]/,
146
- "## [Unreleased]\n\n## [#{@new_version}] - #{today}"
147
- )
148
-
149
- # Update comparison links at bottom
150
- new_content = new_content.gsub(
151
- /\[Unreleased\]: (.+)\/compare\/v(.+?)\.\.\.HEAD/,
152
- "[Unreleased]: \\1/compare/v#{@new_version}...HEAD\n[#{@new_version}]: \\1/compare/v\\2...v#{@new_version}"
153
- )
154
-
155
- File.write(CHANGELOG_FILE, new_content)
156
- end
157
-
158
- def commit_and_tag
159
- step "Committing and tagging"
160
-
161
- tag = "v#{@new_version}"
162
- commit_message = "Bump version to #{@new_version}"
163
-
164
- if @dry_run
165
- puts " [dry-run] Would run: git add -A"
166
- puts " [dry-run] Would run: git commit -m '#{commit_message}'"
167
- puts " [dry-run] Would run: git tag #{tag}"
168
- else
169
- system("git add -A")
170
- system("git commit -m '#{commit_message}'")
171
- system("git tag #{tag}")
172
- puts " ✓ Created commit and tag #{tag}"
173
- end
174
- end
175
-
176
- def push_to_remote
177
- step "Pushing to remote"
178
-
179
- if @dry_run
180
- puts " [dry-run] Would run: git push"
181
- puts " [dry-run] Would run: git push --tags"
182
- else
183
- success = system("git push && git push --tags")
184
- if success
185
- puts " ✓ Pushed commits and tags"
186
- else
187
- error "Failed to push to remote"
188
- end
189
- end
190
- end
191
-
192
- def publish_packages
193
- step "Publishing packages"
194
-
195
- if @dry_run
196
- puts " [dry-run] Would run: bin/release"
197
- return
198
- end
199
-
200
- # Build first
201
- puts " Building packages..."
202
- system("npm run build") || error("npm build failed")
203
- system("gem build shadcn-rails.gemspec") || error("gem build failed")
204
-
205
- gem_file = "shadcn-rails-#{@new_version}.gem"
206
-
207
- # Publish to RubyGems
208
- puts " Publishing to RubyGems..."
209
- unless system("gem push #{gem_file}")
210
- puts " ⚠️ Failed to publish gem (may need: gem signin)"
211
- end
212
-
213
- # Publish to npm
214
- puts " Publishing to npm..."
215
- unless system("npm publish")
216
- puts " ⚠️ Failed to publish to npm (may need: npm login)"
217
- end
218
-
219
- # Clean up
220
- File.delete(gem_file) if File.exist?(gem_file)
221
-
222
- puts " ✓ Published packages"
223
- end
224
-
225
- def print_summary
226
- puts "\n" + "=" * 50
227
- puts "✅ Version bumped to #{@new_version}"
228
- puts "=" * 50
229
-
230
- unless @commit
231
- puts "\nFiles updated. Next steps:"
232
- puts " git add -A"
233
- puts " git commit -m 'Bump version to #{@new_version}'"
234
- puts " git tag v#{@new_version}"
235
- end
236
-
237
- if @commit && !@push && !@release
238
- puts "\nCommitted and tagged. To publish:"
239
- puts " git push && git push --tags"
240
- puts " bin/release"
241
- end
242
-
243
- if @push && !@release
244
- puts "\nPushed to remote. To publish packages:"
245
- puts " bin/release"
246
- end
247
-
248
- if @release
249
- puts "\nRelease complete! 🎉"
250
- end
251
- end
252
-
253
- def step(message)
254
- puts "→ #{message}"
255
- end
256
-
257
- def error(message)
258
- puts "\n❌ Error: #{message}"
259
- exit 1
260
- end
261
- end
262
-
263
- # Parse command line options
264
- options = {
265
- commit: true,
266
- push: false,
267
- release: false,
268
- dry_run: false
269
- }
270
-
271
- parser = OptionParser.new do |opts|
272
- opts.banner = "Usage: bin/bump <patch|minor|major|X.Y.Z> [options]"
273
-
274
- opts.on("--no-commit", "Only update files, don't commit or tag") do
275
- options[:commit] = false
276
- end
277
-
278
- opts.on("--push", "Push commits and tags to remote") do
279
- options[:push] = true
280
- end
281
-
282
- opts.on("--release", "Push and publish to RubyGems and npm") do
283
- options[:release] = true
284
- end
285
-
286
- opts.on("--dry-run", "Show what would happen without making changes") do
287
- options[:dry_run] = true
288
- end
289
-
290
- opts.on("-h", "--help", "Show this help message") do
291
- puts opts
292
- puts "\nExamples:"
293
- puts " bin/bump patch # Bump 0.1.0 → 0.1.1, commit, tag"
294
- puts " bin/bump minor --push # Bump 0.1.0 → 0.2.0, commit, tag, push"
295
- puts " bin/bump major --release # Bump 0.1.0 → 1.0.0, commit, tag, push, publish"
296
- puts " bin/bump 1.0.0 --no-commit # Set to 1.0.0, only update files"
297
- puts " bin/bump patch --dry-run # Preview what would happen"
298
- exit 0
299
- end
300
- end
301
-
302
- parser.parse!
303
-
304
- if ARGV.empty?
305
- # Show current version and help
306
- ruby_version = File.read(VERSION_FILE).match(/VERSION = "(.+?)"/)[1]
307
- puts "Current version: #{ruby_version}"
308
- puts ""
309
- puts parser
310
- exit 1
311
- end
312
-
313
- bump_type = ARGV[0]
314
-
315
- VersionBumper.new(
316
- bump_type: bump_type,
317
- commit: options[:commit],
318
- push: options[:push],
319
- release: options[:release],
320
- dry_run: options[:dry_run]
321
- ).run
data/bin/console DELETED
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "shadcn/rails"
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- require "irb"
11
- IRB.start(__FILE__)