Class: Everywhere::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/everywhere/config.rb

Overview

Loads config/everywhere.yml:

app:
name: My Really Awesome App
entry_path: /dashboard        # initial url on app launch
appearance:
tint_color: "#CC342D"         # a hex string...
background_color:             # ...or split by system theme
  light: "#FAF9F7"
  dark: "#1C1B1A"

Colors always normalize to { "light" => ..., "dark" => ... }.

Constant Summary collapse

FILE =
File.join("config", "everywhere.yml")

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, root) ⇒ Config

Returns a new instance of Config.



29
30
31
32
# File 'lib/everywhere/config.rb', line 29

def initialize(data, root)
  @data = data
  @root = root
end

Instance Attribute Details

#rootObject (readonly)

Returns the value of attribute root.



27
28
29
# File 'lib/everywhere/config.rb', line 27

def root
  @root
end

Class Method Details

.load(root = Dir.pwd) ⇒ Object



21
22
23
24
25
# File 'lib/everywhere/config.rb', line 21

def self.load(root = Dir.pwd)
  path = File.join(root, FILE)
  data = File.exist?(path) ? YAML.safe_load_file(path, aliases: true) || {} : {}
  new(data, root)
end

Instance Method Details

#background_colorObject



106
107
108
# File 'lib/everywhere/config.rb', line 106

def background_color
  normalize_color(appearance["background_color"])
end

#buildObject

The build: section — durable build knobs that were once every build flags (ruby, targets, permissions). CLI flags still override per-run. See platform/docs/build-engine.md §2.



78
# File 'lib/everywhere/config.rb', line 78

def build = @data.fetch("build", nil) || {}

#build_rubyObject

Ruby version to package. nil here means "let the CLI decide its default".



81
# File 'lib/everywhere/config.rb', line 81

def build_ruby = build["ruby"]

#bundle_idObject

Reverse-DNS identifier: macOS bundle id, and the name of the per-user app-data directory on every platform. Set it explicitly and never change it — renaming moves users' data.



41
42
43
# File 'lib/everywhere/config.rb', line 41

def bundle_id
  app["bundle_id"] || "com.rubyeverywhere.#{name.downcase.gsub(/[^a-z0-9]+/, "-").gsub(/\A-|-\z/, "")}"
end

#entry_pathObject



64
65
66
67
# File 'lib/everywhere/config.rb', line 64

def entry_path
  path = app["entry_path"] || "/"
  path.start_with?("/") ? path : "/#{path}"
end

#iconObject

App icon source: a PNG (ideally square, 1024px+). Explicit app.icon path relative to the app root, or icon.png at the root by convention.



47
48
49
50
51
52
53
54
# File 'lib/everywhere/config.rb', line 47

def icon
  if (explicit = app["icon"])
    File.expand_path(explicit, root)
  else
    default = File.join(root, "icon.png")
    File.exist?(default) ? default : nil
  end
end

Custom native menu items (macOS app menu). Each entry: label + path (+ optional accelerator), or "separator". Clicks arrive in the page as "everywhere:menu" events and navigate via Turbo.



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/everywhere/config.rb', line 113

def menu
  entries = @data["menu"]
  return [] unless entries.is_a?(Array)

  entries.filter_map do |item|
    if item == "separator" || (item.is_a?(Hash) && item["separator"])
      { "separator" => true }
    elsif item.is_a?(Hash) && item["label"] && item["path"]
      { "label" => item["label"], "path" => item["path"],
        "accelerator" => item["accelerator"] }.compact
    end
  end
end

#modeObject

"local" — the app is tebako-pressed and runs on-device (default) "remote" — thin shell around an already-deployed app: no press, no sidecar



92
93
94
# File 'lib/everywhere/config.rb', line 92

def mode
  app["mode"] || (remote_url ? "remote" : "local")
end

#nameObject



34
35
36
# File 'lib/everywhere/config.rb', line 34

def name
  app["name"] || File.basename(File.expand_path(root)).split(/[-_]/).map(&:capitalize).join(" ")
end

#permissionsObject

OS-integration permissions the app declares. Recorded in the receipt and (later) used to generate the shell's capabilities.



85
# File 'lib/everywhere/config.rb', line 85

def permissions = Array(build["permissions"])

#remote?Boolean

Returns:

  • (Boolean)


96
# File 'lib/everywhere/config.rb', line 96

def remote? = mode == "remote"

#remote_urlObject



98
99
100
# File 'lib/everywhere/config.rb', line 98

def remote_url
  @data.dig("remote", "url")&.chomp("/")
end

#splashObject

Optional custom splash page (HTML file, path relative to the app root). Shown while the packaged server boots; the shell injects window.EVERYWHERE_CONFIG so it can use the app's name and colors.



59
60
61
62
# File 'lib/everywhere/config.rb', line 59

def splash
  path = app["splash"]
  File.expand_path(path, root) if path
end

#targetsObject

Build targets (os-arch strings) — the CI matrix, expressed once.



88
# File 'lib/everywhere/config.rb', line 88

def targets = Array(build["targets"])

#tint_colorObject



102
103
104
# File 'lib/everywhere/config.rb', line 102

def tint_color
  normalize_color(appearance["tint_color"])
end

#to_shell_hashObject

The subset the shell needs, shipped as JSON (env var in dev, Resources/everywhere.json inside a bundled .app).



153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/everywhere/config.rb', line 153

def to_shell_hash
  {
    "name" => name,
    "bundle_id" => bundle_id,
    "mode" => mode,
    "remote_url" => remote_url,
    "entry_path" => entry_path,
    "tint_color" => tint_color,
    "background_color" => background_color,
    "menu" => (menu unless menu.empty?),
    "tray" => (tray unless tray.empty?)
  }.compact
end

#to_shell_jsonObject



167
168
169
170
# File 'lib/everywhere/config.rb', line 167

def to_shell_json
  require "json"
  JSON.generate(to_shell_hash)
end

#trayObject

System tray: same entry shape as menu: plus action: quit | show.

tray:
- label: "Open My App"
  action: show
- label: "New Note"
  path: /notes/new
- separator
- label: Quit
  action: quit


137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/everywhere/config.rb', line 137

def tray
  entries = @data["tray"]
  return [] unless entries.is_a?(Array)

  entries.filter_map do |item|
    if item == "separator" || (item.is_a?(Hash) && item["separator"])
      { "separator" => true }
    elsif item.is_a?(Hash) && item["label"] && (item["path"] || item["action"])
      { "label" => item["label"], "path" => item["path"],
        "action" => item["action"] }.compact
    end
  end
end

#versionObject

Marketing/display version of the app (CFBundleShortVersionString, and the version recorded in the build receipt). Defaults conservatively.



71
72
73
# File 'lib/everywhere/config.rb', line 71

def version
  app["version"] || "0.1.0"
end