Class: Everywhere::Commands::Preview
- Inherits:
-
Dry::CLI::Command
- Object
- Dry::CLI::Command
- Everywhere::Commands::Preview
- Includes:
- Everywhere::ChildSupervision
- Defined in:
- lib/everywhere/commands/preview.rb
Overview
Put the running dev server in someone's hand: boot the app, open a Cloudflare tunnel to it, and print a QR code that opens the Jump app (spec: platform/docs/jump.md). The server gets EVERYWHERE_JUMP_TOKEN, so the Jump endpoints in MobileConfigEndpoint / MobileConfigsController are live for exactly as long as this command runs.
Three transports, one seam (tunnel_url):
default cloudflared quick tunnel — free, no account, HTTPS,
best-effort (restarted with a fresh QR if it drops)
--tunnel-name a named tunnel from the developer's own Cloudflare
account, for a stable hostname (--tunnel-host says what
that hostname is — cloudflared doesn't know its own DNS)
--lan no tunnel: the LAN address, for offline use
Constant Summary collapse
- TRYCLOUDFLARE_URL =
%r{https://[a-z0-9-]+\.trycloudflare\.com}- TUNNEL_BOOT_TIMEOUT =
30
Instance Method Summary collapse
Instance Method Details
#call(port: "3000", lan: false, tunnel_name: nil, tunnel_host: nil) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/everywhere/commands/preview.rb', line 50 def call(port: "3000", lan: false, tunnel_name: nil, tunnel_host: nil, **) port = validate_port!(port) # An Integer, because @port is interpolated into the cloudflared command # strings — nothing that reaches a shell should be a free-form String. @port = Integer(port, 10) init_children! @framework = detect_local_framework @config = Everywhere::Config.load(@framework.root) # Multi-use on purpose: a forwarded link must work for a second # coworker's device. Dies with this process — bearers are HMACs over # it, so they die too. @token = SecureRandom.urlsafe_base64(24) @lan = lan if lan @url = lan_url(port) else Shellout.ensure_tool!("cloudflared", "preview shares your app through a Cloudflare tunnel — " \ "install it with `brew install cloudflared` (or use --lan)") (tunnel_name, tunnel_host) @tunnel_name = tunnel_name @tunnel_host = tunnel_host @url = start_tunnel end start_server(port) warn_if_loopback_only if lan # Everything below this line scrolls: the dev server's log starts # flowing the moment a device connects, and the invitation was gone off # the top of the screen with it. The dock pins it instead. @dock = Dock::Info.open(keys: $stdin.tty?) announce wait rescue Interrupt nil ensure # The dock has to let go of the terminal before anything else prints — # teardown_children's own warnings included. teardown_children(before: [-> { @dock&.close }]) end |