yamine 0.15.2 → 0.16.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.
@@ -68,7 +68,8 @@ module Yamine
68
68
  end
69
69
 
70
70
  # Pre-flight: verify runtime dependencies before spawning anything.
71
- # Ruby (bundle check), Node (node_modules present). Returns [ok, fix].
71
+ # Ruby (bundle check), Node (node_modules present — but only when the
72
+ # manifest actually declares dependencies). Returns [ok, fix].
72
73
  # Fast-fails with the fix instead of letting Puma crash-loop for 60s.
73
74
  def check_deps(dir = Dir.pwd)
74
75
  gemfile = File.join(dir, "Gemfile")
@@ -80,7 +81,8 @@ module Yamine
80
81
  end
81
82
  end
82
83
  package = File.join(dir, "package.json")
83
- if File.file?(package) && !File.directory?(File.join(dir, "node_modules"))
84
+ if File.file?(package) && !File.directory?(File.join(dir, "node_modules")) &&
85
+ package_declares_dependencies?(package)
84
86
  return [false, "node_modules missing — run `npm install` in #{dir}"]
85
87
  end
86
88
  [true, nil]
@@ -88,6 +90,29 @@ module Yamine
88
90
  [false, e.message.lines.first&.strip]
89
91
  end
90
92
 
93
+ # Does this manifest need an install at all? A stub `{}`
94
+ # (dependency-less apps keep one so tooling finds a manifest) has
95
+ # nothing to install — `npm install` creates no node_modules for
96
+ # it — and demanding the directory would fail every fresh clone
97
+ # and worktree of such an app forever. An unreadable manifest
98
+ # keeps the old directory check: honest conservatism.
99
+ def package_declares_dependencies?(path)
100
+ data = JSON.parse(File.read(path))
101
+ return false unless data.is_a?(Hash)
102
+
103
+ %w[dependencies devDependencies optionalDependencies peerDependencies workspaces]
104
+ .any? do |key|
105
+ value = data[key]
106
+ if value.is_a?(Hash) || value.is_a?(Array)
107
+ !value.empty?
108
+ else
109
+ !value.nil?
110
+ end
111
+ end
112
+ rescue JSON::ParserError, SystemCallError
113
+ true
114
+ end
115
+
91
116
  # Poll an HTTP route until healthy or timeout. Healthy = healthcheck
92
117
  # path returns 2xx-3xx, or (no healthcheck) TCP accept on the port.
93
118
  # Returns [healthy, detail].
data/lib/yamine/runner.rb CHANGED
@@ -100,11 +100,11 @@ module Yamine
100
100
  # yamine's own keys (PORT, YAMINE_URL, DATABASE_URL, the TLS vars)
101
101
  # win over it, because those describe the boot rather than the app.
102
102
  def boot_run(name:, hostname:, url:, dir:, command:, port: nil, force: false,
103
- rails_dev_host: nil, register: true, database_url: nil, spec: nil,
104
- extra_env: nil, subdomains: false)
103
+ rails_dev_host: nil, register: true, database_url: nil, database_env: nil,
104
+ spec: nil, extra_env: nil, subdomains: false)
105
105
  port ||= Ports.find_free
106
106
  env = child_env(dir, url: url, port: port, rails_dev_host: rails_dev_host,
107
- database_url: database_url, extra_env: extra_env)
107
+ database_url: database_url, database_env: database_env, extra_env: extra_env)
108
108
  path = log_path(dir, name)
109
109
  pid = with_clean_env { spawn(env, *command, chdir: dir, out: path, err: [:child, :out]) }
110
110
  Process.detach(pid)
@@ -131,9 +131,9 @@ module Yamine
131
131
  # Returns the placeholder App (target known before bind). Fate of
132
132
  # the backend is decided by wait, not by spawn.
133
133
  def spawn_http(name:, hostname:, url:, dir:, command:, port:, rails_dev_host: nil,
134
- database_url: nil, force: false, extra_env: nil)
134
+ database_url: nil, database_env: nil, force: false, extra_env: nil)
135
135
  env = child_env(dir, url: url, port: port, rails_dev_host: rails_dev_host,
136
- database_url: database_url, extra_env: extra_env)
136
+ database_url: database_url, database_env: database_env, extra_env: extra_env)
137
137
  path = log_path(dir, name)
138
138
  pid = with_clean_env { spawn(env, *command, chdir: dir, out: path, err: [:child, :out]) }
139
139
  Process.detach(pid)
@@ -158,7 +158,8 @@ module Yamine
158
158
  false
159
159
  end
160
160
 
161
- def child_env(dir, url:, port:, rails_dev_host: nil, database_url: nil, extra_env: nil)
161
+ def child_env(dir, url:, port:, rails_dev_host: nil, database_url: nil,
162
+ database_env: nil, extra_env: nil)
162
163
  # The config's own variables first, so everything below overrides
163
164
  # them: PORT, YAMINE_URL, DATABASE_URL, and the TLS paths describe
164
165
  # *this boot* and must not be lost to a stray key in local.yml.
@@ -190,10 +191,17 @@ module Yamine
190
191
  # proxied hostname so Rails apps boot behind yamine with zero
191
192
  # config — this replaces the yamine-rails hosts patch.
192
193
  env["RAILS_DEVELOPMENT_HOSTS"] = rails_dev_host if rails_dev_host
193
- # Per-worktree database: every process in this worktree shares one
194
- # isolated database. Frameworks that honor DATABASE_URL (Rails,
195
- # Django, most Node) get isolation for free; others ignore it.
196
- env["DATABASE_URL"] = database_url if database_url
194
+ # Per-worktree databases: the whole isolated set this checkout
195
+ # claims — DATABASE_URL for primary plus NAME_DATABASE_URL per
196
+ # extra config (Rails' own convention), so a multi-database app
197
+ # gets every database redirected, not just the first. Frameworks
198
+ # that honor DATABASE_URL (Rails, Django, most Node) get
199
+ # isolation for free; others ignore it.
200
+ if database_env
201
+ database_env.each { |k, v| env[k.to_s] = v.to_s if v }
202
+ elsif database_url
203
+ env["DATABASE_URL"] = database_url
204
+ end
197
205
  env
198
206
  end
199
207
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yamine
4
- VERSION = "0.15.2"
4
+ VERSION = "0.16.0"
5
5
  end
data/lib/yamine.rb CHANGED
@@ -4,6 +4,7 @@ require_relative "yamine/version"
4
4
  require_relative "yamine/errors"
5
5
  require_relative "yamine/agent"
6
6
  require_relative "yamine/database"
7
+ require_relative "yamine/probe"
7
8
  require_relative "yamine/sanitize"
8
9
  require_relative "yamine/hostname"
9
10
  require_relative "yamine/inference"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yamine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.2
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -103,6 +103,7 @@ files:
103
103
  - lib/yamine/log.rb
104
104
  - lib/yamine/ownership.rb
105
105
  - lib/yamine/ports.rb
106
+ - lib/yamine/probe.rb
106
107
  - lib/yamine/procfile.rb
107
108
  - lib/yamine/proxy.rb
108
109
  - lib/yamine/proxy_control.rb