shadcn-rails 0.1.0 ā 0.2.0
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 +4 -4
- data/CHANGELOG.md +4 -1
- data/CLAUDE.md +151 -2
- data/PROGRESS.md +30 -20
- data/README.md +89 -1398
- data/Rakefile +66 -0
- data/__tests__/controllers/combobox_controller.test.js +56 -51
- data/__tests__/controllers/context_menu_controller.test.js +280 -2
- data/__tests__/controllers/menubar_controller.test.js +5 -4
- data/__tests__/controllers/navigation_menu_controller.test.js +5 -4
- data/__tests__/controllers/popover_controller.test.js +35 -60
- data/__tests__/controllers/select_controller.test.js +5 -1
- data/app/assets/javascripts/shadcn/controllers/base_menu_controller.js +266 -0
- data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +13 -8
- data/app/assets/javascripts/shadcn/controllers/command_controller.js +5 -1
- data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +61 -105
- data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +49 -170
- data/app/assets/javascripts/shadcn/controllers/menubar_controller.js +10 -7
- data/app/assets/javascripts/shadcn/controllers/navigation_menu_controller.js +10 -6
- data/app/assets/javascripts/shadcn/controllers/popover_controller.js +7 -7
- data/app/assets/javascripts/shadcn/controllers/select_controller.js +12 -10
- data/app/assets/javascripts/shadcn/controllers/sidebar_controller.js +24 -14
- data/app/assets/javascripts/shadcn/index.js +2 -0
- data/app/assets/stylesheets/shadcn/components.css +12 -0
- data/app/components/shadcn/command_list_component.rb +29 -14
- data/app/components/shadcn/context_menu_checkbox_item_component.rb +76 -0
- data/app/components/shadcn/context_menu_content_component.rb +37 -14
- data/app/components/shadcn/context_menu_item_component.rb +3 -2
- data/app/components/shadcn/context_menu_radio_group_component.rb +42 -0
- data/app/components/shadcn/context_menu_radio_item_component.rb +76 -0
- data/app/components/shadcn/dropdown_menu_checkbox_item_component.rb +76 -0
- data/app/components/shadcn/dropdown_menu_content_component.rb +45 -16
- data/app/components/shadcn/dropdown_menu_radio_group_component.rb +42 -0
- data/app/components/shadcn/dropdown_menu_radio_item_component.rb +76 -0
- data/app/components/shadcn/menubar_content_component.rb +45 -20
- data/app/components/shadcn/menubar_sub_content_component.rb +21 -8
- data/app/components/shadcn/radio_group_item_component.rb +32 -6
- data/app/components/shadcn/resizable_panel_group_component.rb +27 -16
- data/app/components/shadcn/select_component.rb +23 -6
- data/bin/bump +321 -0
- data/bin/release +205 -0
- data/bin/test +75 -0
- data/jest.config.js +1 -1
- data/lib/shadcn/rails/version.rb +1 -1
- data/package-lock.json +27 -4
- data/package.json +4 -1
- metadata +11 -1
data/bin/bump
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
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/release
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Release script for shadcn-rails
|
|
5
|
+
# Publishes both Ruby gem and npm package
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bin/release # Release current version
|
|
9
|
+
# bin/release --dry-run # Show what would be released without publishing
|
|
10
|
+
|
|
11
|
+
require "json"
|
|
12
|
+
require "open3"
|
|
13
|
+
|
|
14
|
+
VERSION_FILE = File.expand_path("../lib/shadcn/rails/version.rb", __dir__)
|
|
15
|
+
PACKAGE_JSON = File.expand_path("../package.json", __dir__)
|
|
16
|
+
GEMSPEC_FILE = File.expand_path("../shadcn-rails.gemspec", __dir__)
|
|
17
|
+
|
|
18
|
+
class Release
|
|
19
|
+
def initialize(dry_run: false)
|
|
20
|
+
@dry_run = dry_run
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def run
|
|
24
|
+
puts "\nš shadcn-rails Release\n"
|
|
25
|
+
puts "=" * 50
|
|
26
|
+
|
|
27
|
+
check_clean_working_directory
|
|
28
|
+
check_versions_in_sync
|
|
29
|
+
run_tests
|
|
30
|
+
build_packages
|
|
31
|
+
publish_packages unless @dry_run
|
|
32
|
+
create_github_release unless @dry_run
|
|
33
|
+
|
|
34
|
+
puts "\nā
Release complete!"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def ruby_version
|
|
40
|
+
content = File.read(VERSION_FILE)
|
|
41
|
+
content.match(/VERSION = "(.+?)"/)[1]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def npm_version
|
|
45
|
+
package = JSON.parse(File.read(PACKAGE_JSON))
|
|
46
|
+
package["version"]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def check_clean_working_directory
|
|
50
|
+
step "Checking working directory"
|
|
51
|
+
|
|
52
|
+
status, = run_command("git status --porcelain")
|
|
53
|
+
unless status.empty?
|
|
54
|
+
error "Working directory is not clean. Please commit or stash changes."
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
success "Working directory is clean"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def check_versions_in_sync
|
|
61
|
+
step "Checking version sync"
|
|
62
|
+
|
|
63
|
+
rv = ruby_version
|
|
64
|
+
nv = npm_version
|
|
65
|
+
|
|
66
|
+
if rv != nv
|
|
67
|
+
error "Versions are out of sync!\n Ruby: #{rv}\n npm: #{nv}\n\nRun: bin/bump-version #{rv}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
@version = rv
|
|
71
|
+
success "Versions in sync: #{@version}"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def run_tests
|
|
75
|
+
step "Running tests"
|
|
76
|
+
|
|
77
|
+
_, success = run_command("bin/test", stream: true)
|
|
78
|
+
error "Tests failed" unless success
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def build_packages
|
|
82
|
+
step "Building packages"
|
|
83
|
+
|
|
84
|
+
# Build npm package
|
|
85
|
+
puts " Building npm package..."
|
|
86
|
+
_, success = run_command("npm run build")
|
|
87
|
+
error "npm build failed" unless success
|
|
88
|
+
|
|
89
|
+
# Build gem
|
|
90
|
+
puts " Building gem..."
|
|
91
|
+
_, success = run_command("gem build #{GEMSPEC_FILE}")
|
|
92
|
+
error "gem build failed" unless success
|
|
93
|
+
|
|
94
|
+
@gem_file = "shadcn-rails-#{@version}.gem"
|
|
95
|
+
unless File.exist?(@gem_file)
|
|
96
|
+
error "Gem file not found: #{@gem_file}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
success "Packages built successfully"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def publish_packages
|
|
103
|
+
step "Publishing packages"
|
|
104
|
+
|
|
105
|
+
# Publish to RubyGems
|
|
106
|
+
puts " Publishing to RubyGems..."
|
|
107
|
+
_, success = run_command("gem push #{@gem_file}")
|
|
108
|
+
unless success
|
|
109
|
+
puts " ā ļø Failed to publish gem (may need: gem signin)"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Publish to npm
|
|
113
|
+
puts " Publishing to npm..."
|
|
114
|
+
_, success = run_command("npm publish")
|
|
115
|
+
unless success
|
|
116
|
+
puts " ā ļø Failed to publish to npm (may need: npm login)"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Clean up gem file
|
|
120
|
+
File.delete(@gem_file) if File.exist?(@gem_file)
|
|
121
|
+
|
|
122
|
+
success "Packages published"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def create_github_release
|
|
126
|
+
step "Creating GitHub release"
|
|
127
|
+
|
|
128
|
+
# Check if gh CLI is available
|
|
129
|
+
_, success = run_command("which gh")
|
|
130
|
+
unless success
|
|
131
|
+
puts " ā ļø GitHub CLI not found. Skipping GitHub release."
|
|
132
|
+
puts " Install with: brew install gh"
|
|
133
|
+
return
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Create tag if it doesn't exist
|
|
137
|
+
tag = "v#{@version}"
|
|
138
|
+
_, tag_exists = run_command("git rev-parse #{tag}")
|
|
139
|
+
|
|
140
|
+
unless tag_exists
|
|
141
|
+
puts " Creating tag #{tag}..."
|
|
142
|
+
run_command("git tag #{tag}")
|
|
143
|
+
run_command("git push origin #{tag}")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Create GitHub release
|
|
147
|
+
puts " Creating GitHub release..."
|
|
148
|
+
changelog_section = extract_changelog_section
|
|
149
|
+
|
|
150
|
+
run_command(%(gh release create #{tag} --title "v#{@version}" --notes "#{changelog_section}" #{@gem_file}))
|
|
151
|
+
|
|
152
|
+
success "GitHub release created"
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def extract_changelog_section
|
|
156
|
+
return "Release v#{@version}" unless File.exist?("CHANGELOG.md")
|
|
157
|
+
|
|
158
|
+
content = File.read("CHANGELOG.md")
|
|
159
|
+
# Extract section for current version
|
|
160
|
+
match = content.match(/## \[#{Regexp.escape(@version)}\].*?\n(.*?)(?=\n## \[|$)/m)
|
|
161
|
+
match ? match[1].strip : "Release v#{@version}"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def step(message)
|
|
165
|
+
puts "\nš¦ #{message}..."
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def success(message)
|
|
169
|
+
puts " ā #{message}"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def error(message)
|
|
173
|
+
puts "\nā Error: #{message}"
|
|
174
|
+
exit 1
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def run_command(cmd, stream: false)
|
|
178
|
+
if @dry_run && cmd.match?(/gem push|npm publish|gh release|git tag|git push/)
|
|
179
|
+
puts " [DRY RUN] Would run: #{cmd}"
|
|
180
|
+
return ["", true]
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
if stream
|
|
184
|
+
success = system(cmd)
|
|
185
|
+
["", success]
|
|
186
|
+
else
|
|
187
|
+
output, status = Open3.capture2e(cmd)
|
|
188
|
+
[output.strip, status.success?]
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Parse arguments
|
|
194
|
+
dry_run = ARGV.include?("--dry-run")
|
|
195
|
+
|
|
196
|
+
if ARGV.include?("--help") || ARGV.include?("-h")
|
|
197
|
+
puts "Usage: bin/release [options]"
|
|
198
|
+
puts ""
|
|
199
|
+
puts "Options:"
|
|
200
|
+
puts " --dry-run Show what would be released without publishing"
|
|
201
|
+
puts " --help Show this help message"
|
|
202
|
+
exit 0
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
Release.new(dry_run: dry_run).run
|
data/bin/test
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Run all tests (Ruby and JavaScript)
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# bin/test # Run all tests
|
|
8
|
+
# bin/test ruby # Run only Ruby tests
|
|
9
|
+
# bin/test js # Run only JavaScript tests
|
|
10
|
+
|
|
11
|
+
require "open3"
|
|
12
|
+
|
|
13
|
+
class TestRunner
|
|
14
|
+
def initialize(filter: nil)
|
|
15
|
+
@filter = filter
|
|
16
|
+
@failed = false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run
|
|
20
|
+
puts "\nš§Ŗ Running tests\n"
|
|
21
|
+
puts "=" * 50
|
|
22
|
+
|
|
23
|
+
run_ruby_tests if @filter.nil? || @filter == "ruby"
|
|
24
|
+
run_js_tests if @filter.nil? || @filter == "js"
|
|
25
|
+
|
|
26
|
+
puts "\n" + "=" * 50
|
|
27
|
+
if @failed
|
|
28
|
+
puts "ā Some tests failed"
|
|
29
|
+
exit 1
|
|
30
|
+
else
|
|
31
|
+
puts "ā
All tests passed"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def run_ruby_tests
|
|
38
|
+
step "Ruby tests"
|
|
39
|
+
success = system("bundle exec rake test")
|
|
40
|
+
@failed = true unless success
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def run_js_tests
|
|
44
|
+
step "JavaScript tests"
|
|
45
|
+
success = system("npm test")
|
|
46
|
+
@failed = true unless success
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def step(name)
|
|
50
|
+
puts "\nā #{name}\n\n"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Parse arguments
|
|
55
|
+
filter = case ARGV[0]
|
|
56
|
+
when "ruby", "rb"
|
|
57
|
+
"ruby"
|
|
58
|
+
when "js", "javascript", "node"
|
|
59
|
+
"js"
|
|
60
|
+
when "-h", "--help"
|
|
61
|
+
puts "Usage: bin/test [ruby|js]"
|
|
62
|
+
puts ""
|
|
63
|
+
puts " bin/test Run all tests"
|
|
64
|
+
puts " bin/test ruby Run only Ruby tests"
|
|
65
|
+
puts " bin/test js Run only JavaScript tests"
|
|
66
|
+
exit 0
|
|
67
|
+
when nil
|
|
68
|
+
nil
|
|
69
|
+
else
|
|
70
|
+
puts "Unknown filter: #{ARGV[0]}"
|
|
71
|
+
puts "Use: bin/test [ruby|js]"
|
|
72
|
+
exit 1
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
TestRunner.new(filter: filter).run
|
data/jest.config.js
CHANGED
data/lib/shadcn/rails/version.rb
CHANGED
data/package-lock.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
2
|
+
"name": "shadcn-rails-stimulus",
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
|
-
"name": "
|
|
8
|
+
"name": "shadcn-rails-stimulus",
|
|
9
9
|
"version": "0.1.0",
|
|
10
10
|
"license": "MIT",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"stimulus-use": "^0.52.3"
|
|
13
|
+
},
|
|
11
14
|
"devDependencies": {
|
|
12
15
|
"@babel/core": "^7.28.5",
|
|
13
16
|
"@babel/preset-env": "^7.28.5",
|
|
@@ -1962,8 +1965,8 @@
|
|
|
1962
1965
|
"version": "3.2.2",
|
|
1963
1966
|
"resolved": "https://registry.npmjs.org/@hotwired/stimulus/-/stimulus-3.2.2.tgz",
|
|
1964
1967
|
"integrity": "sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==",
|
|
1965
|
-
"
|
|
1966
|
-
"
|
|
1968
|
+
"license": "MIT",
|
|
1969
|
+
"peer": true
|
|
1967
1970
|
},
|
|
1968
1971
|
"node_modules/@isaacs/cliui": {
|
|
1969
1972
|
"version": "8.0.2",
|
|
@@ -4403,6 +4406,16 @@
|
|
|
4403
4406
|
"node": ">= 0.4"
|
|
4404
4407
|
}
|
|
4405
4408
|
},
|
|
4409
|
+
"node_modules/hotkeys-js": {
|
|
4410
|
+
"version": "3.13.15",
|
|
4411
|
+
"resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.13.15.tgz",
|
|
4412
|
+
"integrity": "sha512-gHh8a/cPTCpanraePpjRxyIlxDFrIhYqjuh01UHWEwDpglJKCnvLW8kqSx5gQtOuSsJogNZXLhOdbSExpgUiqg==",
|
|
4413
|
+
"license": "MIT",
|
|
4414
|
+
"peer": true,
|
|
4415
|
+
"funding": {
|
|
4416
|
+
"url": "https://jaywcjlove.github.io/#/sponsor"
|
|
4417
|
+
}
|
|
4418
|
+
},
|
|
4406
4419
|
"node_modules/html-encoding-sniffer": {
|
|
4407
4420
|
"version": "4.0.0",
|
|
4408
4421
|
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
|
|
@@ -6577,6 +6590,16 @@
|
|
|
6577
6590
|
"node": ">=10"
|
|
6578
6591
|
}
|
|
6579
6592
|
},
|
|
6593
|
+
"node_modules/stimulus-use": {
|
|
6594
|
+
"version": "0.52.3",
|
|
6595
|
+
"resolved": "https://registry.npmjs.org/stimulus-use/-/stimulus-use-0.52.3.tgz",
|
|
6596
|
+
"integrity": "sha512-stZ5dID6FUrGCR/ChWUa0FT5Z8iqkzT6lputOAb50eF+Ayg7RzJj4U/HoRlp2NV333QfvoRidru9HLbom4hZVw==",
|
|
6597
|
+
"license": "MIT",
|
|
6598
|
+
"peerDependencies": {
|
|
6599
|
+
"@hotwired/stimulus": ">= 3",
|
|
6600
|
+
"hotkeys-js": ">= 3"
|
|
6601
|
+
}
|
|
6602
|
+
},
|
|
6580
6603
|
"node_modules/string-length": {
|
|
6581
6604
|
"version": "4.0.2",
|
|
6582
6605
|
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
|
data/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shadcn-rails-stimulus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Stimulus controllers for shadcn-rails ViewComponents",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
"bugs": {
|
|
51
51
|
"url": "https://github.com/iheanyi/shadcn-rails/issues"
|
|
52
52
|
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"stimulus-use": "^0.52.3"
|
|
55
|
+
},
|
|
53
56
|
"peerDependencies": {
|
|
54
57
|
"@hotwired/stimulus": "^3.0.0"
|
|
55
58
|
},
|