dip 8.1.0 → 8.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b6092ebf900ada263123eecb33ee04460d0d8c03421d7f77b99486b6a66941f
4
- data.tar.gz: f2753b321d575b0417ca3153283d8181fdf78f9d75a393c0df74671b0343e8ab
3
+ metadata.gz: f0797622a68dc23c6c015addd9a97dfe57d9c5cca6b4981054dbac9f5f7602c9
4
+ data.tar.gz: bdb1277acfa498846fdd737a13058dc1dfc272fbd7196d21e4cbfeefaf13b3a6
5
5
  SHA512:
6
- metadata.gz: 4b8bd274d40759d1bcb770d9bc6318980d6de06ce6a2f8e6569b7605cdbe9e77b205480bbf7436ee415bad24176ee90928f450875c33aa6cb997f70f6ba4425b
7
- data.tar.gz: dd228653949ce59936aa21b1e63c2f624c522c4fa050eba9f484180e87eccf3b06a44f173cdbbd682d1f6b1045540aaf6af33a194c6ba09ba7c6468031b1adbe
6
+ metadata.gz: 826f6e63b2cd65d20f6bfc00b545a7b5f60d6068786df01f841d92de1179d69fcced9605f65a3e4bfbcace583e5a20e7e8a660359ff2922685a02fae60c8c5c3
7
+ data.tar.gz: 5e583069000503b70df8a8466605d905c4937b931b53734de57486662a93a1f1991a51363e46687eeb4664879ece0ae1c9db56f9a76b57a6e5c478fa5e8d4ee9
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.0"
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
+ "^[a-zA-Z0-9_]+$": {
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
+ "^[a-zA-Z0-9_]+$": {
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
+ "^[a-zA-Z0-9_]+$": {
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.0
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-25 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.