ruflet 0.0.17 → 0.0.18
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/README.md +1 -40
- data/lib/ruflet/cli/build_command.rb +124 -697
- data/lib/ruflet/cli/extra_command.rb +3 -15
- data/lib/ruflet/cli/flutter_sdk.rb +9 -91
- data/lib/ruflet/cli/new_command.rb +7 -36
- data/lib/ruflet/cli/run_command.rb +97 -186
- data/lib/ruflet/cli/templates.rb +8 -9
- data/lib/ruflet/cli.rb +0 -13
- data/lib/ruflet/version.rb +1 -1
- metadata +1 -3
- data/lib/ruflet/cli/android_sdk.rb +0 -306
- data/lib/ruflet/cli/environment_setup.rb +0 -241
|
@@ -12,23 +12,16 @@ require "uri"
|
|
|
12
12
|
require "thread"
|
|
13
13
|
require "io/console"
|
|
14
14
|
require "time"
|
|
15
|
-
require "yaml"
|
|
16
15
|
|
|
17
16
|
module Ruflet
|
|
18
17
|
module CLI
|
|
19
18
|
module RunCommand
|
|
20
|
-
DEFAULT_BACKEND_PORTS = {
|
|
21
|
-
"web" => 8550,
|
|
22
|
-
"desktop" => 8560,
|
|
23
|
-
"mobile" => 8570
|
|
24
|
-
}.freeze
|
|
25
|
-
|
|
26
19
|
def command_run(args)
|
|
27
|
-
options = { target: "mobile", requested_port:
|
|
20
|
+
options = { target: "mobile", requested_port: 8550 }
|
|
28
21
|
parser = OptionParser.new do |o|
|
|
29
22
|
o.on("--web") { options[:target] = "web" }
|
|
30
23
|
o.on("--desktop") { options[:target] = "desktop" }
|
|
31
|
-
o.on("--port PORT", Integer
|
|
24
|
+
o.on("--port PORT", Integer) { |v| options[:requested_port] = v }
|
|
32
25
|
end
|
|
33
26
|
parser.parse!(args)
|
|
34
27
|
|
|
@@ -40,33 +33,18 @@ module Ruflet
|
|
|
40
33
|
return 1
|
|
41
34
|
end
|
|
42
35
|
|
|
43
|
-
|
|
44
|
-
selected_port = resolve_backend_port(options[:target], requested_port: requested_port)
|
|
36
|
+
selected_port = resolve_backend_port(options[:target], requested_port: options[:requested_port])
|
|
45
37
|
return 1 unless selected_port
|
|
46
38
|
env = {
|
|
47
39
|
"RUFLET_TARGET" => options[:target],
|
|
48
40
|
"RUFLET_SUPPRESS_SERVER_BANNER" => "1",
|
|
49
|
-
"RUFLET_PORT" => selected_port.to_s
|
|
50
|
-
"RUFLET_STRICT_PORT" => "1"
|
|
41
|
+
"RUFLET_PORT" => selected_port.to_s
|
|
51
42
|
}
|
|
52
43
|
apply_local_ruflet_dev_overrides(env)
|
|
53
44
|
assets_dir = File.join(File.dirname(script_path), "assets")
|
|
54
45
|
env["RUFLET_ASSETS_DIR"] = assets_dir if File.directory?(assets_dir)
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
# origin/port as /ws), so no separate static server or proxy is needed.
|
|
58
|
-
if options[:target] == "web"
|
|
59
|
-
web_dir = detect_web_client_dir
|
|
60
|
-
if web_dir
|
|
61
|
-
env["RUFLET_WEB_CLIENT_DIR"] = web_dir
|
|
62
|
-
else
|
|
63
|
-
warn "Ruflet web client unavailable for version #{ruflet_version}."
|
|
64
|
-
warn "Install the matching GitHub release client before running --web."
|
|
65
|
-
return 1
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
print_run_banner(target: options[:target], requested_port: requested_port, port: selected_port)
|
|
47
|
+
print_run_banner(target: options[:target], requested_port: options[:requested_port], port: selected_port)
|
|
70
48
|
print_mobile_qr_hint(port: selected_port) if options[:target] == "mobile"
|
|
71
49
|
|
|
72
50
|
gemfile_path = find_nearest_gemfile(Dir.pwd)
|
|
@@ -171,14 +149,16 @@ module Ruflet
|
|
|
171
149
|
|
|
172
150
|
def print_run_banner(target:, requested_port:, port:)
|
|
173
151
|
if port != requested_port.to_i
|
|
174
|
-
puts "
|
|
152
|
+
puts "Requested port #{requested_port} is busy; bound to #{port}"
|
|
175
153
|
end
|
|
176
154
|
if target == "desktop"
|
|
177
155
|
puts "Ruflet desktop URL: http://localhost:#{port}"
|
|
178
156
|
elsif target == "mobile"
|
|
179
157
|
puts "Ruflet target: #{target}"
|
|
158
|
+
else
|
|
159
|
+
puts "Ruflet target: #{target}"
|
|
160
|
+
puts "Ruflet URL: http://localhost:#{port}"
|
|
180
161
|
end
|
|
181
|
-
# web: launch_web_client prints the single app URL after the server boots
|
|
182
162
|
end
|
|
183
163
|
|
|
184
164
|
def launch_target_client(target, port)
|
|
@@ -194,19 +174,30 @@ module Ruflet
|
|
|
194
174
|
end
|
|
195
175
|
end
|
|
196
176
|
|
|
197
|
-
# The Ruby backend (Ruflet::Server) serves the Flutter web client on its
|
|
198
|
-
# own port, so the client loads and opens its websocket on that same
|
|
199
|
-
# origin. The prebuilt web client derives its backend from Uri.base, so
|
|
200
|
-
# the public URL stays clean and dynamic port selection works naturally.
|
|
201
177
|
def launch_web_client(port)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
178
|
+
web_dir = detect_web_client_dir
|
|
179
|
+
unless web_dir
|
|
180
|
+
warn "Web client build not found and prebuilt download failed."
|
|
181
|
+
return []
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
web_port = find_available_port(port + 1)
|
|
185
|
+
web_pid = Process.spawn("python3", "-m", "http.server", web_port.to_s, "--bind", "127.0.0.1", chdir: web_dir, out: File::NULL, err: File::NULL)
|
|
186
|
+
Process.detach(web_pid)
|
|
187
|
+
wait_for_server_boot(web_port)
|
|
188
|
+
backend_url = "http://localhost:#{port}"
|
|
189
|
+
web_url = "http://localhost:#{web_port}/?#{URI.encode_www_form(url: backend_url)}"
|
|
190
|
+
browser_pid = open_in_browser_app_mode(web_url)
|
|
191
|
+
open_in_browser(web_url) if browser_pid.nil?
|
|
192
|
+
puts "Ruflet web client: #{web_url}"
|
|
193
|
+
puts "Ruflet backend ws: ws://localhost:#{port}/ws"
|
|
194
|
+
[web_pid, browser_pid].compact
|
|
195
|
+
rescue Errno::ENOENT
|
|
196
|
+
warn "python3 is required to host web client locally."
|
|
197
|
+
warn "Install Python 3 and rerun."
|
|
198
|
+
[]
|
|
207
199
|
rescue StandardError => e
|
|
208
|
-
warn "Failed to
|
|
209
|
-
warn "Open it manually: http://localhost:#{port}/"
|
|
200
|
+
warn "Failed to launch web client: #{e.class}: #{e.message}"
|
|
210
201
|
[]
|
|
211
202
|
end
|
|
212
203
|
|
|
@@ -316,36 +307,45 @@ module Ruflet
|
|
|
316
307
|
end
|
|
317
308
|
|
|
318
309
|
def detect_desktop_client_command(url)
|
|
319
|
-
root =
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
cached_root = ensure_prebuilt_client(desktop: true)
|
|
325
|
-
desktop_client_command_from_root(cached_root, url)
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
def desktop_client_command_from_root(root, url)
|
|
310
|
+
root = ENV["RUFLET_CLIENT_DIR"]
|
|
311
|
+
root = File.expand_path("ruflet_client", Dir.pwd) if root.to_s.strip.empty?
|
|
312
|
+
root = nil unless Dir.exist?(root)
|
|
313
|
+
root ||= ensure_prebuilt_client(desktop: true)
|
|
329
314
|
return nil unless root && Dir.exist?(root)
|
|
330
315
|
|
|
331
316
|
host_os = RbConfig::CONFIG["host_os"]
|
|
332
317
|
if host_os.match?(/darwin/i)
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
318
|
+
release_bin = File.join(root, "build", "macos", "Build", "Products", "Release", "ruflet_client.app", "Contents", "MacOS", "ruflet_client")
|
|
319
|
+
debug_bin = File.join(root, "build", "macos", "Build", "Products", "Debug", "ruflet_client.app", "Contents", "MacOS", "ruflet_client")
|
|
320
|
+
prebuilt_bin = File.join(root, "desktop", "ruflet_client.app", "Contents", "MacOS", "ruflet_client")
|
|
321
|
+
executable = [release_bin, debug_bin].find { |p| File.file?(p) && File.executable?(p) }
|
|
322
|
+
executable ||= prebuilt_bin if File.file?(prebuilt_bin) && File.executable?(prebuilt_bin)
|
|
323
|
+
return [executable, url] if executable
|
|
336
324
|
elsif host_os.match?(/mswin|mingw|cygwin/i)
|
|
337
|
-
exe = File.join(root, "
|
|
325
|
+
exe = File.join(root, "build", "windows", "x64", "runner", "Release", "ruflet_client.exe")
|
|
326
|
+
prebuilt = File.join(root, "desktop", "ruflet_client.exe")
|
|
327
|
+
exe = prebuilt if !File.file?(exe) && File.file?(prebuilt)
|
|
338
328
|
return [exe, url] if File.file?(exe)
|
|
339
329
|
else
|
|
340
|
-
direct = File.join(root, "
|
|
330
|
+
direct = File.join(root, "build", "linux", "x64", "release", "bundle", "ruflet_client")
|
|
331
|
+
prebuilt_direct = File.join(root, "desktop", "ruflet_client")
|
|
332
|
+
direct = prebuilt_direct if !File.file?(direct) && File.file?(prebuilt_direct)
|
|
341
333
|
return [direct, url] if File.file?(direct)
|
|
334
|
+
bundle_dir = File.join(root, "build", "linux", "x64", "release", "bundle")
|
|
335
|
+
if Dir.exist?(bundle_dir)
|
|
336
|
+
candidate = Dir.children(bundle_dir).map { |f| File.join(bundle_dir, f) }
|
|
337
|
+
.find { |path| File.file?(path) && File.executable?(path) }
|
|
338
|
+
return [candidate, url] if candidate
|
|
339
|
+
end
|
|
342
340
|
end
|
|
343
341
|
|
|
344
342
|
nil
|
|
345
343
|
end
|
|
346
344
|
|
|
347
345
|
def detect_web_client_dir
|
|
348
|
-
root =
|
|
346
|
+
root = ENV["RUFLET_CLIENT_DIR"]
|
|
347
|
+
root = File.expand_path("ruflet_client", Dir.pwd) if root.to_s.strip.empty?
|
|
348
|
+
root = nil unless Dir.exist?(root)
|
|
349
349
|
root ||= ensure_prebuilt_client(web: true)
|
|
350
350
|
return nil unless root && Dir.exist?(root)
|
|
351
351
|
|
|
@@ -357,14 +357,6 @@ module Ruflet
|
|
|
357
357
|
nil
|
|
358
358
|
end
|
|
359
359
|
|
|
360
|
-
def configured_client_root
|
|
361
|
-
root = ENV["RUFLET_CLIENT_DIR"].to_s.strip
|
|
362
|
-
return nil if root.empty?
|
|
363
|
-
|
|
364
|
-
expanded = File.expand_path(root)
|
|
365
|
-
Dir.exist?(expanded) ? expanded : nil
|
|
366
|
-
end
|
|
367
|
-
|
|
368
360
|
def ensure_prebuilt_client(web: false, desktop: false, platform: nil, force: false)
|
|
369
361
|
platform ||= host_platform_name
|
|
370
362
|
return nil if platform.nil?
|
|
@@ -379,12 +371,10 @@ module Ruflet
|
|
|
379
371
|
return nil if desktop_asset.nil?
|
|
380
372
|
wanted_assets << { kind: :desktop, name: desktop_asset, platform: platform }
|
|
381
373
|
end
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if !force && (wanted_assets.empty? || compatible_cache)
|
|
374
|
+
if !force && (wanted_assets.empty? || prebuilt_assets_present?(cache_root, web: web, desktop: desktop, platform: platform))
|
|
375
|
+
ensure_client_manifest(cache_root, platform: platform)
|
|
385
376
|
return cache_root
|
|
386
377
|
end
|
|
387
|
-
force = true if cached && !compatible_cache
|
|
388
378
|
|
|
389
379
|
release = fetch_release_for_version
|
|
390
380
|
return nil unless release
|
|
@@ -446,9 +436,7 @@ module Ruflet
|
|
|
446
436
|
|
|
447
437
|
case platform
|
|
448
438
|
when "macos"
|
|
449
|
-
|
|
450
|
-
bin = File.join(app_path, "Contents", "MacOS", "ruflet_client")
|
|
451
|
-
File.file?(bin) && ensure_macos_file_picker_entitlement(app_path)
|
|
439
|
+
File.file?(File.join(root, "desktop", "ruflet_client.app", "Contents", "MacOS", "ruflet_client"))
|
|
452
440
|
when "linux"
|
|
453
441
|
File.file?(File.join(root, "desktop", "ruflet_client"))
|
|
454
442
|
when "windows"
|
|
@@ -480,33 +468,11 @@ module Ruflet
|
|
|
480
468
|
end
|
|
481
469
|
|
|
482
470
|
def fetch_release_for_version
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
nil
|
|
489
|
-
end
|
|
490
|
-
|
|
491
|
-
def client_release_tags
|
|
492
|
-
channel = ENV["RUFLET_CLIENT_CHANNEL"].to_s.strip
|
|
493
|
-
unless channel.empty?
|
|
494
|
-
raise ArgumentError, "Invalid RUFLET_CLIENT_CHANNEL" unless channel.match?(/\A[A-Za-z0-9._-]+\z/)
|
|
495
|
-
|
|
496
|
-
return [channel]
|
|
497
|
-
end
|
|
498
|
-
|
|
499
|
-
["v#{ruflet_version}", ruflet_version]
|
|
500
|
-
end
|
|
501
|
-
|
|
502
|
-
def compatible_client_cache?(root, platform:)
|
|
503
|
-
manifest = read_client_manifest(root)
|
|
504
|
-
return false unless manifest
|
|
505
|
-
|
|
506
|
-
manifest["schema"] == 1 &&
|
|
507
|
-
manifest["ruflet_version"] == ruflet_version &&
|
|
508
|
-
manifest["platform"] == platform &&
|
|
509
|
-
client_release_tags.include?(manifest["release_tag"])
|
|
471
|
+
release_by_tag("v#{ruflet_version}") ||
|
|
472
|
+
release_by_tag(ruflet_version) ||
|
|
473
|
+
release_by_tag("prebuild") ||
|
|
474
|
+
release_by_tag("prebuild-main") ||
|
|
475
|
+
release_latest
|
|
510
476
|
end
|
|
511
477
|
|
|
512
478
|
def ruflet_version
|
|
@@ -516,59 +482,16 @@ module Ruflet
|
|
|
516
482
|
Ruflet::VERSION
|
|
517
483
|
end
|
|
518
484
|
|
|
485
|
+
def release_latest
|
|
486
|
+
github_get_json("https://api.github.com/repos/AdamMusa/Ruflet/releases/latest")
|
|
487
|
+
end
|
|
488
|
+
|
|
519
489
|
def release_by_tag(tag)
|
|
520
490
|
github_get_json("https://api.github.com/repos/AdamMusa/Ruflet/releases/tags/#{tag}")
|
|
521
491
|
rescue StandardError
|
|
522
492
|
nil
|
|
523
493
|
end
|
|
524
494
|
|
|
525
|
-
def ensure_macos_file_picker_entitlement(app_path)
|
|
526
|
-
return true if macos_app_has_file_picker_entitlement?(app_path)
|
|
527
|
-
|
|
528
|
-
Dir.mktmpdir("ruflet-entitlements-") do |dir|
|
|
529
|
-
entitlements_path = File.join(dir, "ruflet_file_picker.entitlements")
|
|
530
|
-
File.write(entitlements_path, macos_file_picker_entitlements_plist)
|
|
531
|
-
system(
|
|
532
|
-
"/usr/bin/codesign",
|
|
533
|
-
"--force",
|
|
534
|
-
"--deep",
|
|
535
|
-
"--sign",
|
|
536
|
-
"-",
|
|
537
|
-
"--entitlements",
|
|
538
|
-
entitlements_path,
|
|
539
|
-
app_path,
|
|
540
|
-
out: File::NULL,
|
|
541
|
-
err: File::NULL
|
|
542
|
-
)
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
macos_app_has_file_picker_entitlement?(app_path)
|
|
546
|
-
end
|
|
547
|
-
|
|
548
|
-
def macos_app_has_file_picker_entitlement?(app_path)
|
|
549
|
-
output = IO.popen(["/usr/bin/codesign", "-d", "--entitlements", ":-", app_path], err: [:child, :out], &:read)
|
|
550
|
-
$?.success? && output.include?("com.apple.security.files.user-selected.read-write")
|
|
551
|
-
rescue StandardError
|
|
552
|
-
false
|
|
553
|
-
end
|
|
554
|
-
|
|
555
|
-
def macos_file_picker_entitlements_plist
|
|
556
|
-
<<~PLIST
|
|
557
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
558
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
559
|
-
<plist version="1.0">
|
|
560
|
-
<dict>
|
|
561
|
-
\t<key>com.apple.security.app-sandbox</key>
|
|
562
|
-
\t<true/>
|
|
563
|
-
\t<key>com.apple.security.files.user-selected.read-write</key>
|
|
564
|
-
\t<true/>
|
|
565
|
-
\t<key>com.apple.security.network.client</key>
|
|
566
|
-
\t<true/>
|
|
567
|
-
</dict>
|
|
568
|
-
</plist>
|
|
569
|
-
PLIST
|
|
570
|
-
end
|
|
571
|
-
|
|
572
495
|
def fallback_release_asset(assets, wanted)
|
|
573
496
|
kind = wanted[:kind]
|
|
574
497
|
platform = wanted[:platform]
|
|
@@ -607,8 +530,6 @@ module Ruflet
|
|
|
607
530
|
return JSON.parse(response.body) if response.is_a?(Net::HTTPSuccess)
|
|
608
531
|
|
|
609
532
|
raise "GitHub API failed (#{response.code})"
|
|
610
|
-
rescue OpenSSL::SSL::SSLError
|
|
611
|
-
JSON.parse(curl_get(url, headers: ["Accept: application/vnd.github+json", "User-Agent: ruflet-cli"]))
|
|
612
533
|
end
|
|
613
534
|
|
|
614
535
|
def download_file(url, destination, limit: 5)
|
|
@@ -630,31 +551,6 @@ module Ruflet
|
|
|
630
551
|
end
|
|
631
552
|
end
|
|
632
553
|
end
|
|
633
|
-
rescue OpenSSL::SSL::SSLError
|
|
634
|
-
curl_download(url, destination)
|
|
635
|
-
end
|
|
636
|
-
|
|
637
|
-
def curl_get(url, headers: [])
|
|
638
|
-
args = ["curl", "-fsSL"]
|
|
639
|
-
headers.each do |header|
|
|
640
|
-
args += ["-H", header]
|
|
641
|
-
end
|
|
642
|
-
args << url
|
|
643
|
-
output = IO.popen(args, err: File::NULL, &:read)
|
|
644
|
-
return output if $?.success?
|
|
645
|
-
|
|
646
|
-
raise "curl failed while requesting #{url}"
|
|
647
|
-
rescue Errno::ENOENT
|
|
648
|
-
raise "Ruby SSL verification failed and curl is not available"
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
def curl_download(url, destination)
|
|
652
|
-
ok = system("curl", "-fL", "--retry", "2", "--connect-timeout", "20", "-o", destination, url, out: File::NULL, err: File::NULL)
|
|
653
|
-
return destination if ok
|
|
654
|
-
|
|
655
|
-
raise "curl failed while downloading #{url}"
|
|
656
|
-
rescue Errno::ENOENT
|
|
657
|
-
raise "Ruby SSL verification failed and curl is not available"
|
|
658
554
|
end
|
|
659
555
|
|
|
660
556
|
def extract_archive(archive, destination)
|
|
@@ -685,6 +581,19 @@ module Ruflet
|
|
|
685
581
|
nil
|
|
686
582
|
end
|
|
687
583
|
|
|
584
|
+
def ensure_client_manifest(root, platform:)
|
|
585
|
+
return if read_client_manifest(root)
|
|
586
|
+
|
|
587
|
+
assets = []
|
|
588
|
+
assets << { "kind" => "web", "platform" => platform, "asset_name" => nil } if File.file?(File.join(root, "web", "index.html"))
|
|
589
|
+
if prebuilt_desktop_present?(root, platform: platform)
|
|
590
|
+
assets << { "kind" => "desktop", "platform" => platform, "asset_name" => nil }
|
|
591
|
+
end
|
|
592
|
+
return if assets.empty?
|
|
593
|
+
|
|
594
|
+
write_client_manifest(root, platform: platform, release: nil, assets: assets)
|
|
595
|
+
end
|
|
596
|
+
|
|
688
597
|
def write_client_manifest(root, platform:, release:, assets:)
|
|
689
598
|
FileUtils.mkdir_p(root)
|
|
690
599
|
payload = {
|
|
@@ -717,24 +626,26 @@ module Ruflet
|
|
|
717
626
|
port = start_port.to_i
|
|
718
627
|
|
|
719
628
|
max_attempts.times do
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
629
|
+
begin
|
|
630
|
+
begin
|
|
631
|
+
probe = TCPServer.new("0.0.0.0", port)
|
|
632
|
+
rescue Errno::EACCES, Errno::EPERM
|
|
633
|
+
probe = TCPServer.new("127.0.0.1", port)
|
|
634
|
+
end
|
|
635
|
+
probe.close
|
|
636
|
+
return port
|
|
637
|
+
rescue Errno::EADDRINUSE, Errno::EACCES, Errno::EPERM
|
|
638
|
+
port += 1
|
|
639
|
+
end
|
|
723
640
|
end
|
|
724
641
|
|
|
725
|
-
|
|
726
|
-
end
|
|
727
|
-
|
|
728
|
-
def default_backend_port(target)
|
|
729
|
-
DEFAULT_BACKEND_PORTS.fetch(target.to_s, DEFAULT_BACKEND_PORTS.fetch("mobile"))
|
|
642
|
+
start_port
|
|
730
643
|
end
|
|
731
644
|
|
|
732
|
-
def resolve_backend_port(
|
|
645
|
+
def resolve_backend_port(_target, requested_port: 8550)
|
|
733
646
|
base = requested_port.to_i
|
|
734
|
-
base =
|
|
735
|
-
|
|
736
|
-
warn "No available Ruflet port found starting at #{base}." unless selected
|
|
737
|
-
selected
|
|
647
|
+
base = 8550 if base <= 0
|
|
648
|
+
find_available_port(base)
|
|
738
649
|
end
|
|
739
650
|
|
|
740
651
|
def port_available?(port)
|
|
@@ -746,7 +657,7 @@ module Ruflet
|
|
|
746
657
|
probe = TCPServer.new("127.0.0.1", port)
|
|
747
658
|
end
|
|
748
659
|
true
|
|
749
|
-
rescue Errno::EADDRINUSE
|
|
660
|
+
rescue Errno::EADDRINUSE
|
|
750
661
|
false
|
|
751
662
|
ensure
|
|
752
663
|
probe&.close
|
data/lib/ruflet/cli/templates.rb
CHANGED
|
@@ -5,9 +5,16 @@ module Ruflet
|
|
|
5
5
|
MAIN_TEMPLATE = <<~RUBY
|
|
6
6
|
require "ruflet"
|
|
7
7
|
Ruflet.run do |page|
|
|
8
|
-
page.title = "
|
|
8
|
+
page.title = "Counter Demo"
|
|
9
9
|
count = 0
|
|
10
10
|
count_text = text(count.to_s, style: {size: 40})
|
|
11
|
+
page.floating_action_button = fab(
|
|
12
|
+
icon: "add",
|
|
13
|
+
on_click: ->(_e) do
|
|
14
|
+
count += 1
|
|
15
|
+
page.update(count_text, value: count.to_s)
|
|
16
|
+
end
|
|
17
|
+
)
|
|
11
18
|
page.add(
|
|
12
19
|
container(
|
|
13
20
|
expand: true,
|
|
@@ -20,13 +27,6 @@ module Ruflet
|
|
|
20
27
|
count_text
|
|
21
28
|
]
|
|
22
29
|
)
|
|
23
|
-
),
|
|
24
|
-
floating_action_button: fab(
|
|
25
|
-
icon: "add",
|
|
26
|
-
on_click: ->(_e) do
|
|
27
|
-
count += 1
|
|
28
|
-
page.update(count_text, value: count.to_s)
|
|
29
|
-
end
|
|
30
30
|
)
|
|
31
31
|
)
|
|
32
32
|
end
|
|
@@ -36,7 +36,6 @@ module Ruflet
|
|
|
36
36
|
GEMFILE_TEMPLATE = <<~GEMFILE
|
|
37
37
|
source "https://rubygems.org"
|
|
38
38
|
|
|
39
|
-
gem "ruflet", ">= #{Ruflet::VERSION}"
|
|
40
39
|
gem "ruflet_core", ">= #{Ruflet::VERSION}"
|
|
41
40
|
gem "ruflet_server", ">= #{Ruflet::VERSION}"
|
|
42
41
|
GEMFILE
|
data/lib/ruflet/cli.rb
CHANGED
|
@@ -2,23 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require "optparse"
|
|
4
4
|
|
|
5
|
-
# Project files (pbxproj, plists, embedded runtime sources) are UTF-8; never
|
|
6
|
-
# depend on the caller's locale for reading them.
|
|
7
|
-
Encoding.default_external = Encoding::UTF_8 if Encoding.default_external == Encoding::US_ASCII
|
|
8
|
-
|
|
9
|
-
# Provisioning (downloads, package installs, SDK extraction) can run for
|
|
10
|
-
# minutes. When stdout is not a TTY (CI logs, pipes, editor consoles) Ruby
|
|
11
|
-
# buffers it, so progress notes would only appear once the whole run finishes.
|
|
12
|
-
# Unbuffer both streams so the pipeline reports progress as it happens.
|
|
13
|
-
$stdout.sync = true
|
|
14
|
-
$stderr.sync = true
|
|
15
|
-
|
|
16
5
|
require_relative "version"
|
|
17
6
|
require_relative "cli/templates"
|
|
18
7
|
require_relative "cli/new_command"
|
|
19
8
|
require_relative "cli/flutter_sdk"
|
|
20
|
-
require_relative "cli/environment_setup"
|
|
21
|
-
require_relative "cli/android_sdk"
|
|
22
9
|
require_relative "cli/run_command"
|
|
23
10
|
require_relative "cli/update_command"
|
|
24
11
|
require_relative "cli/build_command"
|
data/lib/ruflet/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruflet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.18
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- AdamMusa
|
|
@@ -37,9 +37,7 @@ files:
|
|
|
37
37
|
- assets/splash.png
|
|
38
38
|
- bin/ruflet
|
|
39
39
|
- lib/ruflet/cli.rb
|
|
40
|
-
- lib/ruflet/cli/android_sdk.rb
|
|
41
40
|
- lib/ruflet/cli/build_command.rb
|
|
42
|
-
- lib/ruflet/cli/environment_setup.rb
|
|
43
41
|
- lib/ruflet/cli/extra_command.rb
|
|
44
42
|
- lib/ruflet/cli/flutter_sdk.rb
|
|
45
43
|
- lib/ruflet/cli/new_command.rb
|