@@ -2,10 +2,14 @@ package devconfig
2
2
3
3
import (
4
4
"encoding/json"
5
+ "os"
6
+ "strings"
5
7
6
8
"github.com/pkg/errors"
7
9
orderedmap "github.com/wk8/go-ordered-map/v2"
10
+ "go.jetpack.io/devbox/internal/nix"
8
11
"go.jetpack.io/devbox/internal/searcher"
12
+ "go.jetpack.io/devbox/internal/ux"
9
13
"golang.org/x/exp/slices"
10
14
)
11
15
@@ -55,6 +59,84 @@ func (pkgs *Packages) Remove(versionedName string) {
55
59
})
56
60
}
57
61
62
+ // AddPlatform adds a platform to the list of platforms for a given package
63
+ func (pkgs * Packages ) AddPlatform (versionedname , platform string ) error {
64
+ if err := nix .EnsureValidPlatform (platform ); err != nil {
65
+ return errors .WithStack (err )
66
+ }
67
+
68
+ name , version := parseVersionedName (versionedname )
69
+ for idx , pkg := range pkgs .Collection {
70
+ if pkg .name == name && pkg .Version == version {
71
+
72
+ // Check if the platform is already present
73
+ alreadyPresent := false
74
+ for _ , existing := range pkg .Platforms {
75
+ if existing == platform {
76
+ alreadyPresent = true
77
+ break
78
+ }
79
+ }
80
+
81
+ // Add the platform if it's not already present
82
+ if ! alreadyPresent {
83
+ pkg .Platforms = append (pkg .Platforms , platform )
84
+ }
85
+
86
+ // Adding any platform will restrict installation to it, so
87
+ // the ExcludedPlatforms are no longer needed
88
+ pkg .ExcludedPlatforms = nil
89
+
90
+ pkgs .jsonKind = jsonMap
91
+ pkg .kind = regular
92
+ pkgs .Collection [idx ] = pkg
93
+ return nil
94
+ }
95
+ }
96
+ return errors .Errorf ("package %s not found" , versionedname )
97
+ }
98
+
99
+ // ExcludePlatform adds a platform to the list of excluded platforms for a given package
100
+ func (pkgs * Packages ) ExcludePlatform (versionedName , platform string ) error {
101
+ if err := nix .EnsureValidPlatform (platform ); err != nil {
102
+ return errors .WithStack (err )
103
+ }
104
+
105
+ name , version := parseVersionedName (versionedName )
106
+ for idx , pkg := range pkgs .Collection {
107
+ if pkg .name == name && pkg .Version == version {
108
+
109
+ // Check if the platform is already present
110
+ alreadyPresent := false
111
+ for _ , existing := range pkg .ExcludedPlatforms {
112
+ if existing == platform {
113
+ alreadyPresent = true
114
+ break
115
+ }
116
+ }
117
+
118
+ if ! alreadyPresent {
119
+ pkg .ExcludedPlatforms = append (pkg .ExcludedPlatforms , platform )
120
+ }
121
+ if len (pkg .Platforms ) > 0 {
122
+ ux .Finfo (
123
+ os .Stderr ,
124
+ "Excluding a platform for %[1]s is a bit redundant because it will only be installed on: %[2]v. " +
125
+ "Consider removing the `platform` field from %[1]s's definition in your devbox." +
126
+ "json if you intend for %[1]s to be installed on all platforms except %[3]s.\n " ,
127
+ versionedName , strings .Join (pkg .Platforms , ", " ), platform ,
128
+ )
129
+ }
130
+
131
+ pkgs .jsonKind = jsonMap
132
+ pkg .kind = regular
133
+ pkgs .Collection [idx ] = pkg
134
+ return nil
135
+ }
136
+ }
137
+ return errors .Errorf ("package %s not found" , versionedName )
138
+ }
139
+
58
140
func (pkgs * Packages ) UnmarshalJSON (data []byte ) error {
59
141
60
142
// First, attempt to unmarshal as a list of strings (legacy format)
@@ -123,7 +205,8 @@ type Package struct {
123
205
// deliberately not adding omitempty
124
206
Version string `json:"version"`
125
207
126
- // TODO: add other fields like platforms
208
+ Platforms []string `json:"platforms,omitempty"`
209
+ ExcludedPlatforms []string `json:"excluded_platforms,omitempty"`
127
210
}
128
211
129
212
func NewVersionOnlyPackage (name , version string ) Package {
@@ -143,13 +226,46 @@ func NewPackage(name string, values map[string]any) Package {
143
226
version = ""
144
227
}
145
228
229
+ var platforms []string
230
+ if p , ok := values ["platforms" ]; ok {
231
+ platforms = p .([]string )
232
+ }
233
+ var excludedPlatforms []string
234
+ if e , ok := values ["excluded_platforms" ]; ok {
235
+ excludedPlatforms = e .([]string )
236
+ }
237
+
146
238
return Package {
147
- kind : regular ,
148
- name : name ,
149
- Version : version .(string ),
239
+ kind : regular ,
240
+ name : name ,
241
+ Version : version .(string ),
242
+ Platforms : platforms ,
243
+ ExcludedPlatforms : excludedPlatforms ,
150
244
}
151
245
}
152
246
247
+ // enabledOnPlatform returns whether the package is enabled on the given platform.
248
+ // If the package has a list of platforms, it is enabled only on those platforms.
249
+ // If the package has a list of excluded platforms, it is enabled on all platforms
250
+ // except those.
251
+ func (p * Package ) IsEnabledOnPlatform () bool {
252
+ platform := nix .MustGetSystem ()
253
+ if len (p .Platforms ) > 0 {
254
+ for _ , plt := range p .Platforms {
255
+ if plt == platform {
256
+ return true
257
+ }
258
+ }
259
+ return false
260
+ }
261
+ for _ , plt := range p .ExcludedPlatforms {
262
+ if plt == platform {
263
+ return false
264
+ }
265
+ }
266
+ return true
267
+ }
268
+
153
269
func (p * Package ) VersionedName () string {
154
270
name := p .name
155
271
if p .Version != "" {
@@ -158,11 +274,6 @@ func (p *Package) VersionedName() string {
158
274
return name
159
275
}
160
276
161
- func (p * Package ) IsEnabledOnPlatform () bool {
162
- // TODO savil. Next PR will update this implementation
163
- return true
164
- }
165
-
166
277
func (p * Package ) UnmarshalJSON (data []byte ) error {
167
278
// First, attempt to unmarshal as a version-only string
168
279
var version string
0 commit comments