Repository: compose-spec/compose-go
Pull request #461 (2023-09-20 07:46:47)

introduce `develop` section
This introduces support for `develop` section as defined by https://github.com/compose-spec/compose-spec/pull/253


Patch:
diff --git a/loader/paths.go b/loader/paths.go
index 61e79f0..519a6a6 100644
--- a/loader/paths.go
+++ b/loader/paths.go
@@ -115,6 +115,13 @@ func ResolveServiceRelativePaths(workingDir string, s *types.ServiceConfig) {
 		}
 		s.Volumes[i].Source = resolveMaybeUnixPath(workingDir, vol.Source)
 	}
+
+	if s.Develop != nil {
+		for i, w := range s.Develop.Watch {
+			w.Path = absPath(workingDir, w.Path)
+			s.Develop.Watch[i] = w
+		}
+	}
 }
 
 func absPath(workingDir string, filePath string) string {
diff --git a/schema/compose-spec.json b/schema/compose-spec.json
index d39aa35..ba80eec 100644
--- a/schema/compose-spec.json
+++ b/schema/compose-spec.json
@@ -91,6 +91,7 @@
       "type": "object",
 
       "properties": {
+        "develop": {"$ref": "#/definitions/development"},
         "deploy": {"$ref": "#/definitions/deployment"},
         "annotations": {"$ref": "#/definitions/list_or_dict"},
         "attach": {"type": "boolean"},
@@ -463,6 +464,26 @@
       "additionalProperties": false,
       "patternProperties": {"^x-": {}}
     },
+    "development": {
+      "id": "#/definitions/development",
+      "type": ["object", "null"],
+      "properties": {
+        "watch": {
+          "type": "array",
+          "items": {
+            "type": "object",
+            "properties": {
+              "ignore": {"type": "array", "items": {"type": "string"}},
+              "path": {"type": "string"},
+              "action": {"type": "string", "enum": ["rebuild", "sync"]},
+              "target": {"type": "string"}
+            }
+          },
+          "additionalProperties": false,
+          "patternProperties": {"^x-": {}}
+        }
+      }
+    },
     "deployment": {
       "id": "#/definitions/deployment",
       "type": ["object", "null"],
diff --git a/types/develop.go b/types/develop.go
new file mode 100644
index 0000000..fb58060
--- /dev/null
+++ b/types/develop.go
@@ -0,0 +1,35 @@
+/*
+   Copyright 2020 The Compose Specification Authors.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package types
+
+type DevelopConfig struct {
+	Watch []Trigger `json:"watch,omitempty"`
+}
+
+type WatchAction string
+
+const (
+	WatchActionSync    WatchAction = "sync"
+	WatchActionRebuild WatchAction = "rebuild"
+)
+
+type Trigger struct {
+	Path   string      `json:"path,omitempty"`
+	Action WatchAction `json:"action,omitempty"`
+	Target string      `json:"target,omitempty"`
+	Ignore []string    `json:"ignore,omitempty"`
+}
diff --git a/types/types.go b/types/types.go
index 5864dc0..e8df460 100644
--- a/types/types.go
+++ b/types/types.go
@@ -88,23 +88,24 @@ type ServiceConfig struct {
 	Name     string   `yaml:"-" json:"-"`
 	Profiles []string `yaml:"profiles,omitempty" json:"profiles,omitempty"`
 
-	Annotations  Mapping      `yaml:"annotations,omitempty" json:"annotations,omitempty"`
-	Attach       *bool        `yaml:"attach,omitempty" json:"attach,omitempty"`
-	Build        *BuildConfig `yaml:"build,omitempty" json:"build,omitempty"`
-	BlkioConfig  *BlkioConfig `yaml:"blkio_config,omitempty" json:"blkio_config,omitempty"`
-	CapAdd       []string     `yaml:"cap_add,omitempty" json:"cap_add,omitempty"`
-	CapDrop      []string     `yaml:"cap_drop,omitempty" json:"cap_drop,omitempty"`
-	CgroupParent string       `yaml:"cgroup_parent,omitempty" json:"cgroup_parent,omitempty"`
-	Cgroup       string       `yaml:"cgroup,omitempty" json:"cgroup,omitempty"`
-	CPUCount     int64        `yaml:"cpu_count,omitempty" json:"cpu_count,omitempty"`
-	CPUPercent   float32      `yaml:"cpu_percent,omitempty" json:"cpu_percent,omitempty"`
-	CPUPeriod    int64        `yaml:"cpu_period,omitempty" json:"cpu_period,omitempty"`
-	CPUQuota     int64        `yaml:"cpu_quota,omitempty" json:"cpu_quota,omitempty"`
-	CPURTPeriod  int64        `yaml:"cpu_rt_period,omitempty" json:"cpu_rt_period,omitempty"`
-	CPURTRuntime int64        `yaml:"cpu_rt_runtime,omitempty" json:"cpu_rt_runtime,omitempty"`
-	CPUS         float32      `yaml:"cpus,omitempty" json:"cpus,omitempty"`
-	CPUSet       string       `yaml:"cpuset,omitempty" json:"cpuset,omitempty"`
-	CPUShares    int64        `yaml:"cpu_shares,omitempty" json:"cpu_shares,omitempty"`
+	Annotations  Mapping        `yaml:"annotations,omitempty" json:"annotations,omitempty"`
+	Attach       *bool          `yaml:"attach,omitempty" json:"attach,omitempty"`
+	Build        *BuildConfig   `yaml:"build,omitempty" json:"build,omitempty"`
+	Develop      *DevelopConfig `yaml:"develop,omitempty" json:"develop,omitempty"`
+	BlkioConfig  *BlkioConfig   `yaml:"blkio_config,omitempty" json:"blkio_config,omitempty"`
+	CapAdd       []string       `yaml:"cap_add,omitempty" json:"cap_add,omitempty"`
+	CapDrop      []string       `yaml:"cap_drop,omitempty" json:"cap_drop,omitempty"`
+	CgroupParent string         `yaml:"cgroup_parent,omitempty" json:"cgroup_parent,omitempty"`
+	Cgroup       string         `yaml:"cgroup,omitempty" json:"cgroup,omitempty"`
+	CPUCount     int64          `yaml:"cpu_count,omitempty" json:"cpu_count,omitempty"`
+	CPUPercent   float32        `yaml:"cpu_percent,omitempty" json:"cpu_percent,omitempty"`
+	CPUPeriod    int64          `yaml:"cpu_period,omitempty" json:"cpu_period,omitempty"`
+	CPUQuota     int64          `yaml:"cpu_quota,omitempty" json:"cpu_quota,omitempty"`
+	CPURTPeriod  int64          `yaml:"cpu_rt_period,omitempty" json:"cpu_rt_period,omitempty"`
+	CPURTRuntime int64          `yaml:"cpu_rt_runtime,omitempty" json:"cpu_rt_runtime,omitempty"`
+	CPUS         float32        `yaml:"cpus,omitempty" json:"cpus,omitempty"`
+	CPUSet       string         `yaml:"cpuset,omitempty" json:"cpuset,omitempty"`
+	CPUShares    int64          `yaml:"cpu_shares,omitempty" json:"cpu_shares,omitempty"`
 
 	// Command for the service containers.
 	// If set, overrides COMMAND from the image.


Test patch:
diff --git a/loader/loader_test.go b/loader/loader_test.go
index 35478ed..b40c447 100644
--- a/loader/loader_test.go
+++ b/loader/loader_test.go
@@ -2774,3 +2774,55 @@ services:
 	assert.NilError(t, err)
 	assert.Equal(t, project.Services[0].Image, "nginx:override")
 }
+
+func TestLoadDevelopConfig(t *testing.T) {
+	project, err := Load(buildConfigDetails(`
+name: load-develop
+services:
+  frontend:
+    image: example/webapp
+    build: ./webapp
+    develop:
+      watch: 
+        # sync static content
+        - path: ./webapp/html
+          action: sync
+          target: /var/www
+          ignore:
+            - node_modules/
+
+  backend:
+    image: example/backend
+    build: ./backend
+    develop:
+      watch: 
+        # rebuild image and recreate service
+        - path: ./backend/src
+          action: rebuild
+`, nil), func(options *Options) {
+		options.ResolvePaths = false
+	})
+	assert.NilError(t, err)
+	frontend, err := project.GetService("frontend")
+	assert.NilError(t, err)
+	assert.DeepEqual(t, *frontend.Develop, types.DevelopConfig{
+		Watch: []types.Trigger{
+			{
+				Path:   "./webapp/html",
+				Action: types.WatchActionSync,
+				Target: "/var/www",
+				Ignore: []string{"node_modules/"},
+			},
+		},
+	})
+	backend, err := project.GetService("backend")
+	assert.NilError(t, err)
+	assert.DeepEqual(t, *backend.Develop, types.DevelopConfig{
+		Watch: []types.Trigger{
+			{
+				Path:   "./backend/src",
+				Action: types.WatchActionRebuild,
+			},
+		},
+	})
+}