Skip to content

Commit 93fcd55

Browse files
authored
[plugins] Unify plugin config and devbox config (#1831)
## Summary Changes plugins to use devbox config file struct. Additional fields (e.g. `create_files`) are added to plugin struct, but not devbox config. A few other changes: * readme is deprecated in favor of description. Backward compatible code added. * `__packages` is renamed to `packages`. Structure can now match devbox.json (which means it now allows options like allow_insecure, etc). This field has only ever been public and used for builtins. ## How was it tested? * builds * CICD
1 parent 17c0c80 commit 93fcd55

31 files changed

+73
-80
lines changed

.schema/devbox-plugin.schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"description": "The version of the plugin.",
1818
"type": "string"
1919
},
20-
"readme": {
20+
"description": {
2121
"description": "A short description of the plugin and how it works. This will automatically display when the user first installs the plugin, or runs `devbox info`",
2222
"type": "string"
2323
},

docs/app/docs/guides/creating_plugins.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Plugins are defined as Go JSON Template files, using the following schema:
6363
{
6464
"name": "",
6565
"version": "",
66-
"readme": "",
66+
"description": "",
6767
"env": {
6868
"<key>": "<value>"
6969
},
@@ -153,7 +153,7 @@ The plugin.json below sets the environment variables and config needed to run Mo
153153
{
154154
"name": "mongodb",
155155
"version": "0.0.1",
156-
"readme": "Plugin for the [`mongodb`](https://www.nixhub.io/packages/mongodb) package. This plugin configures MonogoDB to use a local config file and data directory for this project, and configures a mongodb service.",
156+
"description": "Plugin for the [`mongodb`](https://www.nixhub.io/packages/mongodb) package. This plugin configures MonogoDB to use a local config file and data directory for this project, and configures a mongodb service.",
157157
"env": {
158158
"MONGODB_DATA": "{{.Virtenv}}/data",
159159
"MONGODB_CONFIG": "{{.DevboxDir}}/mongod.conf"

examples/plugins/local/my-plugin/my-plugin.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "my-plugin",
33
"version": "0.0.1",
4-
"readme": "Example custom plugin",
4+
"description": "Example custom plugin",
55
"env": {
66
"MY_FOO_VAR": "BAR"
77
},

examples/stacks/lapp-stack/devbox.lock

-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@
279279
},
280280
"php@latest": {
281281
"last_modified": "2024-02-16T04:19:51Z",
282-
"plugin_version": "0.0.3",
283282
"resolved": "github:NixOS/nixpkgs/5e55f0bb65124b05d0a52e164514c03596023634#php83",
284283
"source": "devbox-search",
285284
"version": "8.3.3",

internal/devconfig/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
// Config represents a base devbox.json as well as any imports it may have.
1010
// TODO: All the functions below will be modified to include all imported configs.
1111
type Config struct {
12-
Root configFile
12+
Root ConfigFile
1313

1414
// This will support imports in the future.
1515
// imported []*Config

internal/devconfig/config_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Tests begin by defining their JSON with:
2929
{ "packages": { "go": "latest" } }`)
3030
*/
3131

32-
func parseConfigTxtarTest(t *testing.T, test string) (in *configFile, want []byte) {
32+
func parseConfigTxtarTest(t *testing.T, test string) (in *ConfigFile, want []byte) {
3333
t.Helper()
3434

3535
ar := txtar.Parse([]byte(test))
@@ -701,7 +701,7 @@ func TestDefault(t *testing.T) {
701701
if err != nil {
702702
t.Fatal("got load error:", err)
703703
}
704-
if diff := cmp.Diff(in, &out.Root, cmpopts.IgnoreUnexported(configFile{}, packagesMutator{})); diff != "" {
704+
if diff := cmp.Diff(in, &out.Root, cmpopts.IgnoreUnexported(ConfigFile{}, packagesMutator{})); diff != "" {
705705
t.Errorf("configs not equal (-in +out):\n%s", diff)
706706
}
707707

@@ -727,7 +727,7 @@ func TestNixpkgsValidation(t *testing.T) {
727727
t.Run(name, func(t *testing.T) {
728728
assert := assert.New(t)
729729

730-
err := ValidateNixpkg(&configFile{
730+
err := ValidateNixpkg(&ConfigFile{
731731
Nixpkgs: &NixpkgsConfig{
732732
Commit: testCase.commit,
733733
},

internal/devconfig/env.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package devconfig
22

3-
func (c *configFile) IsEnvsecEnabled() bool {
3+
func (c *ConfigFile) IsEnvsecEnabled() bool {
44
// envsec for legacy.
55
return c.EnvFrom == "envsec" || c.EnvFrom == "jetpack-cloud"
66
}

internal/devconfig/field.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/tailscale/hujson"
88
)
99

10-
func (c *configFile) SetStringField(fieldName, val string) {
10+
func (c *ConfigFile) SetStringField(fieldName, val string) {
1111
valueOfStruct := reflect.ValueOf(c).Elem()
1212

1313
field := valueOfStruct.FieldByName(fieldName)
@@ -16,7 +16,7 @@ func (c *configFile) SetStringField(fieldName, val string) {
1616
c.ast.setStringField(c.jsonNameOfField(fieldName), val)
1717
}
1818

19-
func (c *configFile) jsonNameOfField(fieldName string) string {
19+
func (c *ConfigFile) jsonNameOfField(fieldName string) string {
2020
valueOfStruct := reflect.ValueOf(c).Elem()
2121

2222
var name string

internal/devconfig/file.go

+18-18
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ const (
3333
tsonFormat
3434
)
3535

36-
// configFile defines a devbox environment as JSON.
37-
type configFile struct {
36+
// ConfigFile defines a devbox environment as JSON.
37+
type ConfigFile struct {
3838
Name string `json:"name,omitempty"`
3939
Description string `json:"description,omitempty"`
4040

@@ -82,7 +82,7 @@ type Stage struct {
8282

8383
const DefaultInitHook = "echo 'Welcome to devbox!' > /dev/null"
8484

85-
func DefaultConfig() *configFile {
85+
func DefaultConfig() *ConfigFile {
8686
cfg, err := loadBytes([]byte(fmt.Sprintf(`{
8787
"$schema": "https://raw.githubusercontent.com/jetpack-io/devbox/main/.schema/devbox.schema.json",
8888
"packages": [],
@@ -104,24 +104,24 @@ func DefaultConfig() *configFile {
104104
return cfg
105105
}
106106

107-
func (c *configFile) Bytes() []byte {
107+
func (c *ConfigFile) Bytes() []byte {
108108
b := c.ast.root.Pack()
109109
return bytes.ReplaceAll(b, []byte("\t"), []byte(" "))
110110
}
111111

112-
func (c *configFile) Hash() (string, error) {
112+
func (c *ConfigFile) Hash() (string, error) {
113113
ast := c.ast.root.Clone()
114114
ast.Minimize()
115115
return cachehash.Bytes(ast.Pack())
116116
}
117117

118-
func (c *configFile) Equals(other *configFile) bool {
118+
func (c *ConfigFile) Equals(other *ConfigFile) bool {
119119
hash1, _ := c.Hash()
120120
hash2, _ := other.Hash()
121121
return hash1 == hash2
122122
}
123123

124-
func (c *configFile) NixPkgsCommitHash() string {
124+
func (c *ConfigFile) NixPkgsCommitHash() string {
125125
// The commit hash for nixpkgs-unstable on 2023-10-25 from status.nixos.org
126126
const DefaultNixpkgsCommit = "75a52265bda7fd25e06e3a67dee3f0354e73243c"
127127

@@ -131,23 +131,23 @@ func (c *configFile) NixPkgsCommitHash() string {
131131
return c.Nixpkgs.Commit
132132
}
133133

134-
func (c *configFile) InitHook() *shellcmd.Commands {
134+
func (c *ConfigFile) InitHook() *shellcmd.Commands {
135135
if c == nil || c.Shell == nil {
136-
return nil
136+
return &shellcmd.Commands{}
137137
}
138138
return c.Shell.InitHook
139139
}
140140

141141
// SaveTo writes the config to a file.
142-
func (c *configFile) SaveTo(path string) error {
142+
func (c *ConfigFile) SaveTo(path string) error {
143143
if c.format != jsonFormat {
144144
return errors.New("cannot save config to non-json format")
145145
}
146146
return os.WriteFile(filepath.Join(path, defaultName), c.Bytes(), 0o644)
147147
}
148148

149149
// Get returns the package with the given versionedName
150-
func (c *configFile) GetPackage(versionedName string) (*Package, bool) {
150+
func (c *ConfigFile) GetPackage(versionedName string) (*Package, bool) {
151151
name, version := parseVersionedName(versionedName)
152152
i := c.PackagesMutator.index(name, version)
153153
if i == -1 {
@@ -156,7 +156,7 @@ func (c *configFile) GetPackage(versionedName string) (*Package, bool) {
156156
return &c.PackagesMutator.collection[i], true
157157
}
158158

159-
func loadBytes(b []byte) (*configFile, error) {
159+
func loadBytes(b []byte) (*ConfigFile, error) {
160160
jsonb, err := hujson.Standardize(slices.Clone(b))
161161
if err != nil {
162162
return nil, err
@@ -166,7 +166,7 @@ func loadBytes(b []byte) (*configFile, error) {
166166
if err != nil {
167167
return nil, err
168168
}
169-
cfg := &configFile{
169+
cfg := &ConfigFile{
170170
PackagesMutator: packagesMutator{ast: ast},
171171
ast: ast,
172172
}
@@ -176,7 +176,7 @@ func loadBytes(b []byte) (*configFile, error) {
176176
return cfg, validateConfig(cfg)
177177
}
178178

179-
func LoadConfigFromURL(url string) (*configFile, error) {
179+
func LoadConfigFromURL(url string) (*ConfigFile, error) {
180180
res, err := http.Get(url)
181181
if err != nil {
182182
return nil, errors.WithStack(err)
@@ -190,8 +190,8 @@ func LoadConfigFromURL(url string) (*configFile, error) {
190190
return loadBytes(data)
191191
}
192192

193-
func validateConfig(cfg *configFile) error {
194-
fns := []func(cfg *configFile) error{
193+
func validateConfig(cfg *ConfigFile) error {
194+
fns := []func(cfg *ConfigFile) error{
195195
ValidateNixpkg,
196196
validateScripts,
197197
}
@@ -206,7 +206,7 @@ func validateConfig(cfg *configFile) error {
206206

207207
var whitespace = regexp.MustCompile(`\s`)
208208

209-
func validateScripts(cfg *configFile) error {
209+
func validateScripts(cfg *ConfigFile) error {
210210
scripts := cfg.Scripts()
211211
for k := range scripts {
212212
if strings.TrimSpace(k) == "" {
@@ -224,7 +224,7 @@ func validateScripts(cfg *configFile) error {
224224
return nil
225225
}
226226

227-
func ValidateNixpkg(cfg *configFile) error {
227+
func ValidateNixpkg(cfg *ConfigFile) error {
228228
hash := cfg.NixPkgsCommitHash()
229229
if hash == "" {
230230
return nil

internal/devconfig/scripts.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type script struct {
99

1010
type scripts map[string]*script
1111

12-
func (c *configFile) Scripts() scripts {
12+
func (c *ConfigFile) Scripts() scripts {
1313
if c == nil || c.Shell == nil {
1414
return nil
1515
}

internal/devpkg/package.go

-11
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,6 @@ type Package struct {
9292
normalizedPackageAttributePathCache string // memoized value from normalizedPackageAttributePath()
9393
}
9494

95-
// PackagesFromStringsWithDefaults constructs Package from the list of package names provided.
96-
// These names correspond to devbox packages from the devbox.json config.
97-
func PackagesFromStringsWithDefaults(rawNames []string, l lock.Locker) []*Package {
98-
packages := []*Package{}
99-
for _, rawName := range rawNames {
100-
pkg := PackageFromStringWithDefaults(rawName, l)
101-
packages = append(packages, pkg)
102-
}
103-
return packages
104-
}
105-
10695
func PackagesFromStringsWithOptions(rawNames []string, l lock.Locker, opts devopt.AddOpts) []*Package {
10796
packages := []*Package{}
10897
for _, name := range rawNames {

internal/plugin/hooks.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func (m *Manager) InitHooks(
3131
if c == nil {
3232
continue
3333
}
34-
hooks = append(hooks, c.Shell.InitHook.Cmds...)
34+
hooks = append(hooks, c.InitHook().Cmds...)
3535
}
3636
return hooks, nil
3737
}

internal/plugin/info.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ func Readme(ctx context.Context,
6060
}
6161

6262
func printReadme(cfg *config, w io.Writer, markdown bool) error {
63-
if cfg.Readme == "" {
63+
if cfg.Description() == "" {
6464
return nil
6565
}
6666
_, err := fmt.Fprintf(
6767
w,
6868
"%s%s NOTES:\n%s\n\n",
6969
lo.Ternary(markdown, "### ", ""),
7070
cfg.Name,
71-
cfg.Readme,
71+
cfg.Description(),
7272
)
7373
return errors.WithStack(err)
7474
}

internal/plugin/manager.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99

1010
"github.com/samber/lo"
11+
"go.jetpack.io/devbox/internal/devconfig"
1112
"go.jetpack.io/devbox/internal/devpkg"
1213
"go.jetpack.io/devbox/internal/lock"
1314
)
@@ -64,7 +65,8 @@ func (m *Manager) ProcessPluginPackages(
6465
}
6566
pluginPackages = append(
6667
pluginPackages,
67-
devpkg.PackagesFromStringsWithDefaults(config.Packages, m.lockfile)...,
68+
devpkg.PackagesFromConfig(
69+
&devconfig.Config{Root: config.ConfigFile}, m.lockfile)...,
6870
)
6971
if config.RemoveTriggerPackage {
7072
packagesToRemove = append(packagesToRemove, pkg)

internal/plugin/plugin.go

+15-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package plugin
55

66
import (
77
"bytes"
8+
"cmp"
89
"encoding/json"
910
"io/fs"
1011
"os"
@@ -13,11 +14,11 @@ import (
1314
"text/template"
1415

1516
"github.com/pkg/errors"
17+
"go.jetpack.io/devbox/internal/devconfig"
1618
"go.jetpack.io/devbox/internal/devpkg"
1719

1820
"go.jetpack.io/devbox/internal/conf"
1921
"go.jetpack.io/devbox/internal/debug"
20-
"go.jetpack.io/devbox/internal/devbox/shellcmd"
2122
"go.jetpack.io/devbox/internal/lock"
2223
"go.jetpack.io/devbox/internal/nix"
2324
"go.jetpack.io/devbox/internal/services"
@@ -34,20 +35,15 @@ var (
3435
)
3536

3637
type config struct {
37-
Name string `json:"name"`
38-
Version string `json:"version"`
38+
devconfig.ConfigFile
39+
3940
CreateFiles map[string]string `json:"create_files"`
40-
Packages []string `json:"__packages"`
41-
Env map[string]string `json:"env"`
42-
Readme string `json:"readme"`
41+
42+
DeprecatedDescription string `json:"readme"`
4343
// If true, we remove the package that triggered this plugin from the environment
4444
// Useful when we want to replace with flake
45-
RemoveTriggerPackage bool `json:"__remove_trigger_package,omitempty"`
46-
47-
Shell struct {
48-
// InitHook contains commands that will run at shell startup.
49-
InitHook shellcmd.Commands `json:"init_hook,omitempty"`
50-
} `json:"shell,omitempty"`
45+
RemoveTriggerPackage bool `json:"__remove_trigger_package,omitempty"`
46+
Version string `json:"version"`
5147
}
5248

5349
func (c *config) ProcessComposeYaml() (string, string) {
@@ -281,3 +277,10 @@ func (m *Manager) shouldCreateFile(
281277
// File doesn't exist, so we should create it.
282278
return errors.Is(err, fs.ErrNotExist)
283279
}
280+
281+
func (c *config) Description() string {
282+
if c == nil {
283+
return ""
284+
}
285+
return cmp.Or(c.ConfigFile.Description, c.DeprecatedDescription)
286+
}

plugins/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Plugins are defined as Go JSON Template files, using the following schema:
2525
{
2626
"name": "",
2727
"version": "",
28-
"readme": "",
28+
"description": "",
2929
"env": {
3030
"<key>": "<value>"
3131
},

plugins/apacheHttpd.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "apache",
33
"version": "0.0.2",
4-
"readme": "If you with to edit the config file, please copy it out of the .devbox directory.",
4+
"description": "If you with to edit the config file, please copy it out of the .devbox directory.",
55
"env": {
66
"HTTPD_DEVBOX_CONFIG_DIR": "{{ .DevboxProjectDir }}",
77
"HTTPD_CONFDIR": "{{ .DevboxDir }}",

0 commit comments

Comments
 (0)