captive-stack-detector 0.7.0 → 0.8.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7799cc8a4c640bb12eca8a85e86e4d4e59eaae472764cc07d255f1481d8592c
4
- data.tar.gz: e9481131febb4b7d7e9558ba629941d5d19025fd548b91afe458c71c51280f41
3
+ metadata.gz: 306ad005144b3248ab256849d42f4c0a3e8b87ad366da28881bf5e8e6791351e
4
+ data.tar.gz: 8b4ed7f3d18d757237f10c7960a483ef37b7b70d319cafc7220f40d3f5e817a9
5
5
  SHA512:
6
- metadata.gz: ba37a8e26e9356235db1f390d9d80eefae0eb585f1709f9bb1ef5d8b90ee8c2c82e50506ddebe9fa8ae3a337b096a675e48abd95d8c586130c4ed6416d8c89cf
7
- data.tar.gz: cb1e564350c211cfc8bc1906857e413e099fbe368f5d5d9029a2c7074dbaf168034aa85d5924596606f9ca9d5ded9dcd617559fb95f7befe58e647eaf161078b
6
+ metadata.gz: 62e99f62f25e2bee41ac4ec907df5e043ef9bc5ce38c63a0e056c1bcb887d0a83120b9d77c5a23f0f2739c8fb17702aa76610c47a046fdbe45aa50e680339bc4
7
+ data.tar.gz: 6fdf9d55e74d88766af20d9cd2e371b481fd7aa1c35c33345534d96d6d72fe470853939ce2b6ea5805b6c1e0020334eee0464a76bfac316898c26851df0e6f90
data/docs/stacks.md CHANGED
@@ -15,6 +15,7 @@ gem "rails", "8.1.0"
15
15
  - Avec une gem d'assets (`propshaft`, `sprockets-rails`, `importmap-rails`, `jsbundling-rails`, `cssbundling-rails`, `tailwindcss-rails`…), l'application est construite avec ses assets frontend.
16
16
  - Sans gem d'assets, elle est construite comme une API.
17
17
  - `gem "pg"` provisionne une base Postgres, `gem "redis"` ou `gem "sidekiq"` un Redis.
18
+ - Les bibliothèques système exigées par certaines gems sont installées dans l'image : `ruby-vips` (libvips), `mini_magick` et `rmagick` (imagemagick), `sqlite3`, et `ethon` (libcurl), y compris quand la gem n'arrive qu'en dépendance d'une autre via le `Gemfile.lock`. Pour une bibliothèque non détectée, listez le paquet Debian dans un `Aptfile` à la racine.
18
19
 
19
20
  Si un `Gemfile` est présent, c'est toujours lui qui décide : un dépôt avec un `Gemfile` sans Rails est refusé, même s'il a aussi un `package.json`.
20
21
 
@@ -42,9 +43,11 @@ Votre application est buildée une fois, puis servie en fichiers statiques. Aucu
42
43
  - Toutes les routes inconnues renvoient `index.html` : le routage côté client (React Router, Vue Router…) fonctionne sans configuration.
43
44
  - Les variables d'environnement sont injectées **au moment du build** (par exemple `VITE_SUPABASE_URL`). Après en avoir modifié une, redéployez.
44
45
 
45
- ### Serveur Node (Next.js, Nuxt, SvelteKit, Remix)
46
+ ### Serveur Node (Next.js, Nuxt, SvelteKit, Remix, Astro)
46
47
 
47
- Si votre `package.json` dépend de `next`, `nuxt`, `@sveltejs/kit` ou d'un paquet `@remix-run/…`, Captive lance un vrai serveur Node avec votre script `start`.
48
+ Si votre `package.json` dépend de `next`, `nuxt`, `@sveltejs/kit`, `@astrojs/node` ou d'un paquet `@remix-run/…`, Captive lance un vrai serveur Node avec votre script `start`.
49
+
50
+ Pour Astro, utilisez l'adaptateur `@astrojs/node` en mode `standalone`, avec `output: 'server'`. Le script `start` doit lancer le serveur construit (par exemple `node ./dist/server/entry.mjs`) sur `0.0.0.0`, au port fourni par `PORT`. Les dépendances et les devDependencies sont prises en compte. Astro seul, sans adaptateur Node, reste servi en fichiers statiques.
48
51
 
49
52
  ```json
50
53
  {
@@ -2,7 +2,7 @@
2
2
 
3
3
  module CaptiveStackDetector
4
4
  # Connaissance « quel gem exige quels paquets système ». Rend les paires gem → paquets
5
- # pour les gems effectivement déclarés dans le Gemfile passé.
5
+ # pour les gems déclarés dans le Gemfile ou résolus dans le Gemfile.lock (dépendances transitives).
6
6
  module GemPackageMap
7
7
  MAP = {
8
8
  "ruby-vips" => %w[libvips42 libvips-dev],
@@ -10,11 +10,18 @@ module CaptiveStackDetector
10
10
  "rmagick" => %w[imagemagick],
11
11
  "wkhtmltopdf-binary" => %w[], # retiré de Debian Trixie, projet upstream abandonné
12
12
  "sqlite3" => %w[libsqlite3-dev],
13
+ "ethon" => %w[libcurl4t64], # charge libcurl via FFI (dépendance de typhoeus)
13
14
  }.freeze
14
15
 
15
- def self.matches(gemfile)
16
- content = gemfile.to_s
17
- MAP.select { |gem, _| content.match?(/gem ['"]#{Regexp.escape(gem)}['"]/) }
16
+ def self.matches(*sources)
17
+ content = sources.join("\n")
18
+ MAP.select { |gem, _| content.match?(pattern(gem)) }
19
+ end
20
+
21
+ # Déclaration `gem "x"` du Gemfile, ou spec résolue ` x (1.2.3)` du Gemfile.lock.
22
+ def self.pattern(gem)
23
+ name = Regexp.escape(gem)
24
+ /gem ['"]#{name}['"]|^ {4}#{name} \(/
18
25
  end
19
26
  end
20
27
  end
@@ -5,6 +5,7 @@ require_relative "system_package_detector"
5
5
  require_relative "solid_queue_worker"
6
6
 
7
7
  module CaptiveStackDetector
8
+ # Construit le Result d'une app Rails à partir des fichiers du repo.
8
9
  class RailsStackDetector
9
10
  def initialize(reader, analyzer)
10
11
  @reader = reader
@@ -34,8 +35,9 @@ module CaptiveStackDetector
34
35
 
35
36
  def system_packages
36
37
  SystemPackageDetector.new(
37
- gemfile: @reader.read("Gemfile"),
38
- aptfile: @reader.read("Aptfile"),
38
+ gemfile: @reader.read("Gemfile"),
39
+ aptfile: @reader.read("Aptfile"),
40
+ lockfile: @reader.read("Gemfile.lock"),
39
41
  ).packages
40
42
  end
41
43
  end
@@ -3,7 +3,7 @@
3
3
  module CaptiveStackDetector
4
4
  # Reconnaît les frameworks JS rendus côté serveur (SSR) à partir des dépendances.
5
5
  module SsrFrameworkDetector
6
- FRAMEWORKS = %w[next nuxt @sveltejs/kit].freeze
6
+ FRAMEWORKS = %w[next nuxt @sveltejs/kit @astrojs/node].freeze
7
7
  SCOPES = %w[@remix-run/].freeze
8
8
 
9
9
  def self.server?(deps)
@@ -4,27 +4,32 @@ require_relative "aptfile_parser"
4
4
  require_relative "gem_package_map"
5
5
 
6
6
  module CaptiveStackDetector
7
+ # Paquets APT à installer dans l'image : ceux qu'exigent les gems du Gemfile/Gemfile.lock, plus l'Aptfile.
7
8
  class SystemPackageDetector
8
- def initialize(gemfile:, aptfile:)
9
- @gemfile = gemfile.to_s
9
+ def initialize(gemfile:, aptfile:, lockfile: nil)
10
+ @gem_sources = [ gemfile, lockfile ]
10
11
  @aptfile = aptfile.to_s
11
12
  end
12
13
 
13
14
  def packages
14
15
  result = (from_gemfile + from_aptfile).uniq
15
- $stderr.puts "[captive-stack-detector] paquets système détectés : #{result.any? ? result.join(", ") : "aucun"}"
16
+ $stderr.puts "[captive-stack-detector] paquets système détectés : #{describe(result, "aucun")}"
16
17
  result
17
18
  end
18
19
 
19
20
  private
20
21
 
21
22
  def from_gemfile
22
- GemPackageMap.matches(@gemfile).each_with_object([]) do |(gem, pkgs), result|
23
- $stderr.puts "[captive-stack-detector] gem '#{gem}' détecté → #{pkgs.any? ? pkgs.join(", ") : "aucun paquet"}"
23
+ GemPackageMap.matches(*@gem_sources).each_with_object([]) do |(gem, pkgs), result|
24
+ $stderr.puts "[captive-stack-detector] gem '#{gem}' détecté → #{describe(pkgs, "aucun paquet")}"
24
25
  result.concat(pkgs)
25
26
  end
26
27
  end
27
28
 
29
+ def describe(pkgs, none)
30
+ pkgs.any? ? pkgs.join(", ") : none
31
+ end
32
+
28
33
  def from_aptfile
29
34
  AptfileParser.parse(@aptfile).each do |pkg|
30
35
  $stderr.puts "[captive-stack-detector] Aptfile → paquet '#{pkg}'"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CaptiveStackDetector
4
- VERSION = "0.7.0"
4
+ VERSION = "0.8.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: captive-stack-detector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Captive Studio