@@ -10,6 +10,7 @@ import (
1010 "path/filepath"
1111 "strings"
1212
13+ "github.com/pkg/errors"
1314 "go.jetpack.io/devbox/boxcli/usererr"
1415 "go.jetpack.io/devbox/planner/plansdk"
1516)
@@ -50,6 +51,7 @@ func (p *Planner) GetPlan(srcDir string) *plansdk.Plan {
5051 fmt .Sprintf ("php%s" , v .MajorMinorConcatenated ()),
5152 fmt .Sprintf ("php%sPackages.composer" , v .MajorMinorConcatenated ()),
5253 },
54+ Definitions : p .definitions (srcDir , v ),
5355 }
5456 if ! plansdk .FileExists (filepath .Join (srcDir , "public/index.php" )) {
5557 return plan .WithError (usererr .New ("Can't build. No public/index.php found." ))
@@ -66,28 +68,33 @@ func (p *Planner) GetPlan(srcDir string) *plansdk.Plan {
6668 return plan
6769}
6870
71+ type composerPackages struct {
72+ Config struct {
73+ Platform struct {
74+ PHP string `json:"php"`
75+ } `json:"platform"`
76+ } `json:"config"`
77+ Require map [string ]string `json:"require"`
78+ }
79+
6980func (p * Planner ) version (srcDir string ) * plansdk.Version {
7081 latestVersion , _ := plansdk .NewVersion (supportedPHPVersions [0 ])
71- composerJSONPath := filepath .Join (srcDir , "composer.json" )
72- content , err := os .ReadFile (composerJSONPath )
82+ project , err := p .parseComposerPackages (srcDir )
7383
7484 if err != nil {
7585 return latestVersion
7686 }
7787
78- composerJSON := struct {
79- Config struct {
80- Platform struct {
81- PHP string `json:"php"`
82- } `json:"platform"`
83- } `json:"config"`
84- }{}
85- if err := json .Unmarshal (content , & composerJSON ); err != nil ||
86- composerJSON .Config .Platform .PHP == "" {
88+ composerPHPVersion := project .Require ["php" ]
89+ if composerPHPVersion == "" {
90+ composerPHPVersion = project .Config .Platform .PHP
91+ }
92+
93+ if composerPHPVersion == "" {
8794 return latestVersion
8895 }
8996
90- version , err := plansdk .NewVersion (composerJSON . Config . Platform . PHP )
97+ version , err := plansdk .NewVersion (composerPHPVersion )
9198 if err != nil {
9299 return latestVersion
93100 }
@@ -110,3 +117,49 @@ func (p *Planner) version(srcDir string) *plansdk.Version {
110117 // might as well pick the latest version.
111118 return latestVersion
112119}
120+
121+ func (p * Planner ) definitions (srcDir string , v * plansdk.Version ) []string {
122+ extensions , err := p .extensions (srcDir )
123+ if len (extensions ) == 0 || err != nil {
124+ return []string {}
125+ }
126+ return []string {
127+ fmt .Sprintf (
128+ "php%s = pkgs.php%s.withExtensions ({ enabled, all }: enabled ++ (with all; [ %s ]));" ,
129+ v .MajorMinorConcatenated (),
130+ v .MajorMinorConcatenated (),
131+ strings .Join (extensions , " " ),
132+ ),
133+ }
134+ }
135+
136+ func (p * Planner ) extensions (srcDir string ) ([]string , error ) {
137+ project , err := p .parseComposerPackages (srcDir )
138+ if err != nil {
139+ return nil , errors .WithStack (err )
140+ }
141+
142+ extensions := []string {}
143+ for requirement := range project .Require {
144+ if strings .HasPrefix (requirement , "ext-" ) {
145+ name := strings .Split (requirement , "-" )[1 ]
146+ if name != "" && name != "json" {
147+ extensions = append (extensions , name )
148+ }
149+ }
150+ }
151+
152+ return extensions , nil
153+ }
154+
155+ func (p * Planner ) parseComposerPackages (srcDir string ) (* composerPackages , error ) {
156+ composerJSONPath := filepath .Join (srcDir , "composer.json" )
157+ content , err := os .ReadFile (composerJSONPath )
158+
159+ if err != nil {
160+ return nil , errors .WithStack (err )
161+ }
162+
163+ project := & composerPackages {}
164+ return project , errors .WithStack (json .Unmarshal (content , project ))
165+ }
0 commit comments