dip 8.1.0 → 8.2.1

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: 0b6092ebf900ada263123eecb33ee04460d0d8c03421d7f77b99486b6a66941f
4
- data.tar.gz: f2753b321d575b0417ca3153283d8181fdf78f9d75a393c0df74671b0343e8ab
3
+ metadata.gz: 7b28b63d4e0070c1034ad950d1266862d2c454e866854f2a976eed4699332d91
4
+ data.tar.gz: 383bfce092620e1c9591e0f312d802d480e759a969701bf68d04933d61a5c30f
5
5
  SHA512:
6
- metadata.gz: 4b8bd274d40759d1bcb770d9bc6318980d6de06ce6a2f8e6569b7605cdbe9e77b205480bbf7436ee415bad24176ee90928f450875c33aa6cb997f70f6ba4425b
7
- data.tar.gz: dd228653949ce59936aa21b1e63c2f624c522c4fa050eba9f484180e87eccf3b06a44f173cdbbd682d1f6b1045540aaf6af33a194c6ba09ba7c6468031b1adbe
6
+ metadata.gz: 4381b03ae837b07db75bb867a747c5d2d0ec5a1a6930dff822af84fb2d1bbb779c4eabf51107e737e712c59faf37aac84dd7d7527fc442569504952e840520f4
7
+ data.tar.gz: ae5e0d478a4e6e3d1134ff0ef4b5b7fdce650a3bedfd7f5bf9f9186070d1380666236c10cafc0d6fc2d847fed89109907adf1ce09d98536270b1085a82f86e69
data/README.md CHANGED
@@ -472,6 +472,27 @@ services:
472
472
  user: "1000:1000"
473
473
  ```
474
474
 
475
+ ### dip validate
476
+
477
+ Validates your dip.yml configuration against the JSON schema. The schema validation helps ensure your configuration is correct and follows the expected format.
478
+
479
+ ```sh
480
+ dip validate
481
+ ```
482
+
483
+ The validator will check:
484
+
485
+ - Required properties are present
486
+ - Property types are correct
487
+ - Values match expected patterns
488
+ - No unknown properties are used
489
+
490
+ If validation fails, you'll get detailed error messages indicating what needs to be fixed.
491
+
492
+ You can skip validation by setting `DIP_SKIP_VALIDATION` environment variable.
493
+
494
+ Add `# yaml-language-server: $schema=https://raw.githubusercontent.com/bibendi/dip/refs/heads/master/schema.json` to the top of your dip.yml to get schema validation in VSCode. Read more about [YAML Language Server](https://github.com/redhat-developer/vscode-yaml?tab=readme-ov-file#associating-schemas).
495
+
475
496
  ## Changelog
476
497
 
477
498
  https://github.com/bibendi/dip/releases
data/lib/dip/cli.rb CHANGED
@@ -5,7 +5,7 @@ require "dip/run_vars"
5
5
 
6
6
  module Dip
7
7
  class CLI < Thor
8
- TOP_LEVEL_COMMANDS = %w[help version ls compose up stop down run provision ssh infra console].freeze
8
+ TOP_LEVEL_COMMANDS = %w[help version ls compose up stop down run provision ssh infra console validate]
9
9
 
10
10
  class << self
11
11
  # Hackery. Take the run method away from Thor so that we can redefine it.
@@ -117,6 +117,15 @@ module Dip
117
117
  end
118
118
  end
119
119
 
120
+ desc "validate", "Validate the dip.yml file against the schema"
121
+ def validate
122
+ Dip.config.validate
123
+ puts "dip.yml is valid"
124
+ rescue Dip::Error => e
125
+ warn "Validation failed: #{e.message}"
126
+ exit 1
127
+ end
128
+
120
129
  require_relative "cli/ssh"
121
130
  desc "ssh", "ssh-agent container commands"
122
131
  subcommand :ssh, Dip::CLI::SSH
data/lib/dip/config.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require "yaml"
4
4
  require "erb"
5
5
  require "pathname"
6
+ require "json-schema"
6
7
 
7
8
  require "dip/version"
8
9
  require "dip/ext/hash"
@@ -112,6 +113,24 @@ module Dip
112
113
  end
113
114
  end
114
115
 
116
+ def validate
117
+ raise Dip::Error, "Config file path is not set" if file_path.nil?
118
+ raise Dip::Error, "Config file not found: #{file_path}" unless File.exist?(file_path)
119
+
120
+ schema_path = File.join(File.dirname(__FILE__), "../../schema.json")
121
+ raise Dip::Error, "Schema file not found: #{schema_path}" unless File.exist?(schema_path)
122
+
123
+ data = YAML.load_file(file_path)
124
+ schema = JSON.parse(File.read(schema_path))
125
+ JSON::Validator.validate!(schema, data)
126
+ rescue Psych::SyntaxError => e
127
+ raise Dip::Error, "Invalid YAML syntax in config file: #{e.message}"
128
+ rescue JSON::Schema::ValidationError => e
129
+ data_display = data ? data.to_yaml.gsub("\n", "\n ") : "nil"
130
+ error_message = "Schema validation failed: #{e.message}\nInput data:\n #{data_display}"
131
+ raise Dip::Error, error_message
132
+ end
133
+
115
134
  private
116
135
 
117
136
  attr_reader :work_dir
@@ -129,8 +148,8 @@ module Dip
129
148
 
130
149
  unless Gem::Version.new(Dip::VERSION) >= Gem::Version.new(config.fetch(:version))
131
150
  raise VersionMismatchError, "Your dip version is `#{Dip::VERSION}`, " \
132
- "but config requires minimum version `#{config[:version]}`. " \
133
- "Please upgrade your dip!"
151
+ "but config requires minimum version `#{config[:version]}`. " \
152
+ "Please upgrade your dip!"
134
153
  end
135
154
 
136
155
  base_config = {}
@@ -155,6 +174,12 @@ module Dip
155
174
  base_config.deep_merge!(self.class.load_yaml(override_finder.file_path)) if override_finder.exist?
156
175
 
157
176
  @config = CONFIG_DEFAULTS.merge(base_config)
177
+
178
+ unless ENV.key?("DIP_SKIP_VALIDATION")
179
+ validate
180
+ end
181
+
182
+ @config
158
183
  end
159
184
 
160
185
  def config_missing_error(config_key)
data/lib/dip/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dip
4
- VERSION = "8.1.0"
4
+ VERSION = "8.2.1"
5
5
  end
data/schema.json ADDED
@@ -0,0 +1,224 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-06/schema#",
3
+ "title": "Dip Configuration Schema",
4
+ "description": "Schema for the dip.yml configuration file",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "definitions": {
8
+ "environment_vars": {
9
+ "type": "object",
10
+ "description": "Defines environment variables",
11
+ "additionalProperties": {
12
+ "type": "string"
13
+ },
14
+ "examples": [
15
+ { "RAILS_ENV": "development" },
16
+ { "DATABASE_URL": "postgres://user:password@db:5432/myapp_development" },
17
+ { "PORT": "${PORT:-3000}" }
18
+ ]
19
+ },
20
+ "interaction_command": {
21
+ "type": "object",
22
+ "description": "Configuration for an interaction command",
23
+ "additionalProperties": false,
24
+ "properties": {
25
+ "description": {
26
+ "type": "string",
27
+ "description": "Describes the command",
28
+ "examples": ["Run Rails commands", "Connect to PostgreSQL database"]
29
+ },
30
+ "service": {
31
+ "type": "string",
32
+ "description": "Specifies the service associated with the command",
33
+ "examples": ["web", "frontend", "db"]
34
+ },
35
+ "command": {
36
+ "type": "string",
37
+ "description": "Represents the command to be executed",
38
+ "examples": ["bundle exec rails", "npm", "psql -h db -U user myapp_development"]
39
+ },
40
+ "default_args": {
41
+ "type": "string",
42
+ "description": "Default arguments for the command",
43
+ "examples": ["server -p 3000 -b 0.0.0.0"]
44
+ },
45
+ "environment": {
46
+ "$ref": "#/definitions/environment_vars"
47
+ },
48
+ "compose": {
49
+ "type": "object",
50
+ "description": "Allows specifying Docker Compose options",
51
+ "additionalProperties": false,
52
+ "properties": {
53
+ "method": {
54
+ "type": "string",
55
+ "description": "Specifies the Docker Compose method (e.g., up, run)",
56
+ "examples": ["run", "up"]
57
+ },
58
+ "compose_method": {
59
+ "type": "string",
60
+ "description": "Specifies an alternative Docker Compose method to use in compose commands",
61
+ "examples": ["up"]
62
+ },
63
+ "run_options": {
64
+ "type": "array",
65
+ "items": {
66
+ "type": "string"
67
+ },
68
+ "description": "Options to pass to the 'docker-compose run' command",
69
+ "examples": [["service-ports", "rm"]]
70
+ },
71
+ "profiles": {
72
+ "type": "array",
73
+ "items": {
74
+ "type": "string"
75
+ },
76
+ "description": "Docker Compose profiles to use",
77
+ "examples": [["web", "development"], ["frontend"], ["test"]]
78
+ }
79
+ }
80
+ },
81
+ "shell": {
82
+ "type": "boolean",
83
+ "description": "Enables or disables shell interpolation"
84
+ },
85
+ "entrypoint": {
86
+ "type": "string",
87
+ "description": "Specifies the command entrypoint"
88
+ },
89
+ "runner": {
90
+ "type": "string",
91
+ "description": "Specifies the runner (e.g., docker_compose, kubectl)"
92
+ },
93
+ "subcommands": {
94
+ "type": "object",
95
+ "description": "Contains subcommands with the same structure as main commands",
96
+ "patternProperties": {
97
+ "^[\\w\\-\\.\\:\\/\\s]+$": {
98
+ "$ref": "#/definitions/interaction_command"
99
+ }
100
+ },
101
+ "minProperties": 1,
102
+ "additionalProperties": false
103
+ }
104
+ }
105
+ }
106
+ },
107
+ "properties": {
108
+ "version": {
109
+ "type": "string",
110
+ "description": "Specifies the minimum required version of Dip",
111
+ "examples": ["8.1.0"]
112
+ },
113
+ "compose": {
114
+ "type": "object",
115
+ "description": "Contains Docker Compose configuration",
116
+ "properties": {
117
+ "files": {
118
+ "type": "array",
119
+ "items": {
120
+ "type": "string"
121
+ },
122
+ "description": "Array of strings representing paths to Docker Compose files",
123
+ "examples": [["docker-compose.yml", "docker-compose.override.yml"]]
124
+ },
125
+ "project_name": {
126
+ "type": "string",
127
+ "description": "Specifies the project name for Docker Compose",
128
+ "examples": ["app"]
129
+ },
130
+ "command": {
131
+ "type": "string",
132
+ "description": "Specifies an alternative Docker Compose command",
133
+ "examples": ["docker compose"]
134
+ },
135
+ "method": {
136
+ "type": "string",
137
+ "description": "Specifies the Docker Compose method to use"
138
+ }
139
+ }
140
+ },
141
+ "interaction": {
142
+ "type": "object",
143
+ "description": "Defines the commands and their configurations",
144
+ "patternProperties": {
145
+ "^[\\w\\-\\.\\:\\/\\s]+$": {
146
+ "$ref": "#/definitions/interaction_command"
147
+ }
148
+ },
149
+ "additionalProperties": false
150
+ },
151
+ "provision": {
152
+ "type": "array",
153
+ "items": {
154
+ "type": "string"
155
+ },
156
+ "description": "Lists the commands to be executed for provisioning",
157
+ "examples": [
158
+ [
159
+ "dip compose down --volumes",
160
+ "dip compose build",
161
+ "dip rails db:migrate",
162
+ "dip npm install"
163
+ ]
164
+ ]
165
+ },
166
+ "environment": {
167
+ "$ref": "#/definitions/environment_vars"
168
+ },
169
+ "kubectl": {
170
+ "type": "object",
171
+ "description": "Contains Kubernetes configuration",
172
+ "additionalProperties": false,
173
+ "properties": {
174
+ "namespace": {
175
+ "type": "string",
176
+ "description": "Specifies the Kubernetes namespace to use",
177
+ "examples": ["app"]
178
+ }
179
+ }
180
+ },
181
+ "modules": {
182
+ "type": "array",
183
+ "items": {
184
+ "type": "string"
185
+ },
186
+ "description": "Paths to module configuration files",
187
+ "examples": [["production"]]
188
+ },
189
+ "infra": {
190
+ "type": "object",
191
+ "description": "Contains infrastructure services configuration",
192
+ "additionalProperties": false,
193
+ "patternProperties": {
194
+ "^[\\w\\-\\.\\:\\/\\s]+$": {
195
+ "type": "object",
196
+ "additionalProperties": false,
197
+ "properties": {
198
+ "git": {
199
+ "type": "string",
200
+ "pattern": "^(git@|git://|https?://)[\\w\\d\\.@:\\-/]+$",
201
+ "description": "Git repository URL for the infrastructure component",
202
+ "examples": ["https://github.com/mycompany/redis-config.git"]
203
+ },
204
+ "ref": {
205
+ "type": "string",
206
+ "description": "Specifies the Git reference (branch, tag, or commit) to use",
207
+ "examples": ["main"]
208
+ },
209
+ "path": {
210
+ "type": "string",
211
+ "description": "Local path to the infrastructure component",
212
+ "examples": ["./infra/elasticsearch"]
213
+ }
214
+ },
215
+ "oneOf": [
216
+ { "required": ["git", "ref"] },
217
+ { "required": ["path"] }
218
+ ]
219
+ }
220
+ }
221
+ }
222
+ },
223
+ "required": ["version", "interaction"]
224
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dip
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.1.0
4
+ version: 8.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - bibendi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-01 00:00:00.000000000 Z
11
+ date: 2024-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -30,6 +30,40 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: json-schema
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '5'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '5'
47
+ - !ruby/object:Gem::Dependency
48
+ name: public_suffix
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 2.0.2
54
+ - - "<"
55
+ - !ruby/object:Gem::Version
56
+ version: '6.0'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.0.2
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: '6.0'
33
67
  - !ruby/object:Gem::Dependency
34
68
  name: bundler
35
69
  requirement: !ruby/object:Gem::Requirement
@@ -212,6 +246,7 @@ files:
212
246
  - lib/dip/interaction_tree.rb
213
247
  - lib/dip/run_vars.rb
214
248
  - lib/dip/version.rb
249
+ - schema.json
215
250
  homepage: https://github.com/bibendi/dip
216
251
  licenses:
217
252
  - MIT
@@ -232,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
267
  - !ruby/object:Gem::Version
233
268
  version: '0'
234
269
  requirements: []
235
- rubygems_version: 3.2.32
270
+ rubygems_version: 3.5.21
236
271
  signing_key:
237
272
  specification_version: 4
238
273
  summary: Ruby gem CLI tool for better interacting Docker Compose files.