dagger_ruby 0.7.0 → 0.9.0

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.
data/dagger_ruby.gemspec CHANGED
@@ -5,24 +5,25 @@ require_relative "lib/dagger_ruby/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "dagger_ruby"
7
7
  spec.version = DaggerRuby::VERSION
8
- spec.authors = ["Gaurav Tiwari", "Claude Sonnet 4 + GPT-4"]
9
- spec.email = ["gaurav@gauravtiwari.co.uk"]
10
-
11
- spec.summary = "A Ruby SDK for Dagger - build powerful CI/CD pipelines using Ruby"
12
- # rubocop:disable Layout/LineLength
13
- spec.description = "DaggerRuby provides a fluent, idiomatic Ruby interface to Dagger's container-based CI/CD engine. " \
14
- "Define build pipelines programmatically with Ruby instead of YAML. " \
15
- "Features lazy execution, caching, secrets, and service orchestration."
16
- # rubocop:enable Layout/LineLength
8
+ spec.authors = ["BoringCache"]
9
+ spec.email = ["oss@boringcache.com"]
10
+
11
+ spec.summary = "A Ruby client for Dagger's GraphQL API"
12
+ spec.description = "DaggerRuby provides a small, chainable Ruby interface for running container builds, " \
13
+ "services, caches, secrets, and filesystem operations with the Dagger engine."
17
14
  spec.homepage = "https://github.com/boringcache/dagger_ruby"
18
15
  spec.license = "MIT"
19
- spec.required_ruby_version = ">= 3.1.0"
16
+ spec.required_ruby_version = ">= 4.0.0"
20
17
 
21
18
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
22
19
 
23
20
  spec.metadata["homepage_uri"] = spec.homepage
24
- spec.metadata["source_code_uri"] = "https://github.com/boringcache/dagger_ruby"
25
- spec.metadata["changelog_uri"] = "https://github.com/boringcache/dagger_ruby/blob/main/CHANGELOG.md"
21
+ spec.metadata["source_code_uri"] = "#{spec.homepage}/tree/v#{spec.version}"
22
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
23
+ spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
24
+ spec.metadata["documentation_uri"] = "#{spec.homepage}#readme"
25
+ spec.metadata["security_policy_uri"] = "#{spec.homepage}/security/policy"
26
+ spec.metadata["rubygems_mfa_required"] = "true"
26
27
 
27
28
  # Specify which files should be added to the gem when it is released.
28
29
  spec.files = Dir.glob(%w[
@@ -31,18 +32,14 @@ Gem::Specification.new do |spec|
31
32
  LICENSE*
32
33
  CHANGELOG*
33
34
  README*
34
- .yardopts
35
+ SECURITY*
35
36
  ]).reject { |f| File.directory?(f) }
36
37
 
37
- spec.bindir = "exe"
38
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
39
38
  spec.require_paths = ["lib"]
40
39
 
41
- # Core dependencies - using only Ruby stdlib
42
- spec.add_dependency "base64", "~> 0.1"
43
- spec.add_dependency "json", "~> 2.6"
44
- spec.add_dependency "logger", "~> 1.4"
40
+ spec.add_dependency "base64", "~> 0.3"
41
+ spec.add_dependency "json", "~> 2.21"
42
+ spec.add_dependency "logger", "~> 1.7"
45
43
 
46
44
  # Development dependencies are managed in Gemfile
47
- spec.metadata["rubygems_mfa_required"] = "true"
48
45
  end
@@ -4,20 +4,10 @@ require_relative "dagger_object"
4
4
 
5
5
  module DaggerRuby
6
6
  class CacheVolume < DaggerObject
7
- def self.from_id(id, client)
8
- query = QueryBuilder.new("cacheVolume")
9
- query.load_from_id(id)
10
- new(query, client)
11
- end
12
-
13
7
  def self.root_field_name
14
8
  "cacheVolume"
15
9
  end
16
10
 
17
- def key
18
- get_scalar("key")
19
- end
20
-
21
11
  def sync
22
12
  get_scalar("id") # Force execution by getting ID
23
13
  self
@@ -61,17 +61,24 @@ module DaggerRuby
61
61
  Directory.new(QueryBuilder.new("directory"), self)
62
62
  end
63
63
 
64
- def file
65
- File.new(QueryBuilder.new("file"), self)
64
+ def file(name, contents, permissions: nil)
65
+ args = { "name" => name, "contents" => contents }
66
+ args["permissions"] = permissions if permissions
67
+ File.new(QueryBuilder.new.chain_operation("file", args), self)
66
68
  end
67
69
 
68
- def secret
69
- Secret.new(QueryBuilder.new("secret"), self)
70
+ def secret(uri, cache_key: nil)
71
+ args = { "uri" => uri }
72
+ args["cacheKey"] = cache_key if cache_key
73
+ Secret.new(QueryBuilder.new.chain_operation("secret", args), self)
70
74
  end
71
75
 
72
- def cache_volume(name)
73
- query = QueryBuilder.new
74
- query = query.chain_operation("cacheVolume", { "key" => name })
76
+ def cache_volume(name, opts = {})
77
+ args = { "key" => name }
78
+ args["source"] = graphql_id(opts[:source]) if opts[:source]
79
+ args["sharing"] = QueryBuilder.enum_value(opts[:sharing]) if opts[:sharing]
80
+ args["owner"] = opts[:owner] if opts[:owner]
81
+ query = QueryBuilder.new.chain_operation("cacheVolume", args)
75
82
  CacheVolume.new(query, self)
76
83
  end
77
84
 
@@ -81,21 +88,12 @@ module DaggerRuby
81
88
 
82
89
  def git(url, opts = {})
83
90
  args = { "url" => url }
84
- args["keepGitDir"] = opts[:keep_git_dir] if opts.key?(:keep_git_dir)
85
91
  args["sshKnownHosts"] = opts[:ssh_known_hosts] if opts[:ssh_known_hosts]
86
- if opts[:ssh_auth_socket]
87
- args["sshAuthSocket"] =
88
- opts[:ssh_auth_socket].is_a?(DaggerObject) ? opts[:ssh_auth_socket].id : opts[:ssh_auth_socket]
89
- end
92
+ args["sshAuthSocket"] = graphql_id(opts[:ssh_auth_socket]) if opts[:ssh_auth_socket]
90
93
  args["httpAuthUsername"] = opts[:http_auth_username] if opts[:http_auth_username]
91
- if opts[:http_auth_token]
92
- args["httpAuthToken"] =
93
- opts[:http_auth_token].is_a?(DaggerObject) ? opts[:http_auth_token].id : opts[:http_auth_token]
94
- end
95
- if opts[:http_auth_header]
96
- args["httpAuthHeader"] =
97
- opts[:http_auth_header].is_a?(DaggerObject) ? opts[:http_auth_header].id : opts[:http_auth_header]
98
- end
94
+ args["httpAuthToken"] = graphql_id(opts[:http_auth_token]) if opts[:http_auth_token]
95
+ args["httpAuthHeader"] = graphql_id(opts[:http_auth_header]) if opts[:http_auth_header]
96
+ args["experimentalServiceHost"] = graphql_id(opts[:service_host]) if opts[:service_host]
99
97
 
100
98
  query = QueryBuilder.new
101
99
  query = query.chain_operation("git", args)
@@ -106,10 +104,9 @@ module DaggerRuby
106
104
  args = { "url" => url }
107
105
  args["name"] = opts[:name] if opts[:name]
108
106
  args["permissions"] = opts[:permissions] if opts[:permissions]
109
- if opts[:auth_header]
110
- args["authHeader"] =
111
- opts[:auth_header].is_a?(DaggerObject) ? opts[:auth_header].id : opts[:auth_header]
112
- end
107
+ args["checksum"] = opts[:checksum] if opts[:checksum]
108
+ args["authHeader"] = graphql_id(opts[:auth_header]) if opts[:auth_header]
109
+ args["experimentalServiceHost"] = graphql_id(opts[:service_host]) if opts[:service_host]
113
110
 
114
111
  query = QueryBuilder.new
115
112
  query = query.chain_operation("http", args)
@@ -143,6 +140,10 @@ module DaggerRuby
143
140
 
144
141
  private
145
142
 
143
+ def graphql_id(value)
144
+ value.is_a?(DaggerObject) ? value.id : value
145
+ end
146
+
146
147
  def handle_response(response)
147
148
  case response.code.to_i
148
149
  when 200
@@ -4,12 +4,6 @@ require_relative "dagger_object"
4
4
 
5
5
  module DaggerRuby
6
6
  class Container < DaggerObject
7
- def self.from_id(id, client)
8
- query = QueryBuilder.new("container")
9
- query.load_from_id(id)
10
- new(query, client)
11
- end
12
-
13
7
  def self.root_field_name
14
8
  "container"
15
9
  end
@@ -22,23 +16,28 @@ module DaggerRuby
22
16
  args = { "path" => path, "source" => directory.is_a?(DaggerObject) ? directory.id : directory }
23
17
  args["exclude"] = opts[:exclude] if opts[:exclude]
24
18
  args["include"] = opts[:include] if opts[:include]
19
+ args["gitignore"] = opts[:gitignore] if opts[:gitignore]
25
20
  args["owner"] = opts[:owner] if opts[:owner]
26
21
  args["expand"] = opts[:expand] if opts.key?(:expand)
22
+ args["permissions"] = opts[:permissions] if opts[:permissions]
27
23
 
28
24
  chain_operation("withDirectory", args)
29
25
  end
30
26
 
31
- def with_workdir(path)
32
- chain_operation("withWorkdir", { "path" => path })
27
+ def with_workdir(path, expand: nil)
28
+ args = { "path" => path }
29
+ args["expand"] = expand unless expand.nil?
30
+ chain_operation("withWorkdir", args)
33
31
  end
34
32
 
35
33
  def with_exec(args, opts = {})
36
34
  exec_args = { "args" => args }
37
35
  exec_args["useEntrypoint"] = opts[:use_entrypoint] if opts.key?(:use_entrypoint)
38
36
  exec_args["stdin"] = opts[:stdin] if opts[:stdin]
37
+ exec_args["redirectStdin"] = opts[:redirect_stdin] if opts[:redirect_stdin]
39
38
  exec_args["redirectStdout"] = opts[:redirect_stdout] if opts[:redirect_stdout]
40
39
  exec_args["redirectStderr"] = opts[:redirect_stderr] if opts[:redirect_stderr]
41
- exec_args["expect"] = opts[:expect] if opts[:expect]
40
+ exec_args["expect"] = QueryBuilder.enum_value(opts[:expect]) if opts[:expect]
42
41
  if opts.key?(:experimental_privileged_nesting)
43
42
  exec_args["experimentalPrivilegedNesting"] = opts[:experimental_privileged_nesting]
44
43
  end
@@ -54,7 +53,7 @@ module DaggerRuby
54
53
  def with_mounted_cache(path, cache, opts = {})
55
54
  args = { "path" => path, "cache" => cache.is_a?(DaggerObject) ? cache.id : cache }
56
55
  args["source"] = opts[:source] if opts[:source]
57
- args["sharing"] = opts[:sharing] if opts[:sharing]
56
+ args["sharing"] = QueryBuilder.enum_value(opts[:sharing]) if opts[:sharing]
58
57
  args["owner"] = opts[:owner] if opts[:owner]
59
58
  args["expand"] = opts[:expand] if opts.key?(:expand)
60
59
 
@@ -91,10 +90,7 @@ module DaggerRuby
91
90
  chain_operation("withSecretVariable", args)
92
91
  end
93
92
 
94
- def with_secret_env(name, secret)
95
- args = { "name" => name, "secret" => secret.is_a?(DaggerObject) ? secret.id : secret }
96
- chain_operation("withSecretEnv", args)
97
- end
93
+ alias with_secret_env with_secret_variable
98
94
 
99
95
  def with_entrypoint(args, opts = {})
100
96
  entrypoint_args = { "args" => args }
@@ -106,9 +102,13 @@ module DaggerRuby
106
102
  chain_operation("withUser", { "name" => name })
107
103
  end
108
104
 
109
- def with_registry_auth(_address, _username, _secret)
110
- puts "⚠️ Registry auth temporarily disabled due to GraphQL formatting issues"
111
- self
105
+ def with_registry_auth(address, username, secret)
106
+ args = {
107
+ "address" => address,
108
+ "username" => username,
109
+ "secret" => secret.is_a?(DaggerObject) ? secret.id : secret,
110
+ }
111
+ chain_operation("withRegistryAuth", args)
112
112
  end
113
113
 
114
114
  def without_registry_auth(address)
@@ -139,21 +139,6 @@ module DaggerRuby
139
139
  get_object("asService", Service, args)
140
140
  end
141
141
 
142
- def build(context, opts = {})
143
- args = { "context" => context.is_a?(DaggerObject) ? context.id : context }
144
- args["dockerfile"] = opts[:dockerfile] if opts[:dockerfile]
145
- args["target"] = opts[:target] if opts[:target]
146
- args["buildArgs"] = opts[:build_args] if opts[:build_args]
147
-
148
- if opts[:secrets]
149
- raise NotImplementedError, "Build secrets are not yet supported. Use with_mounted_secret instead."
150
- end
151
-
152
- args["noInit"] = opts[:no_init] if opts.key?(:no_init)
153
-
154
- chain_operation("build", args)
155
- end
156
-
157
142
  def import(source, opts = {})
158
143
  args = { "source" => source.is_a?(DaggerObject) ? source.id : source }
159
144
  args["tag"] = opts[:tag] if opts[:tag]
@@ -179,7 +164,7 @@ module DaggerRuby
179
164
 
180
165
  def with_exposed_port(port, opts = {})
181
166
  args = { "port" => port }
182
- args["protocol"] = opts[:protocol] if opts[:protocol]
167
+ args["protocol"] = QueryBuilder.enum_value(opts[:protocol]) if opts[:protocol]
183
168
  args["description"] = opts[:description] if opts[:description]
184
169
  if opts.key?(:experimental_skip_healthcheck)
185
170
  args["experimentalSkipHealthcheck"] = opts[:experimental_skip_healthcheck]
@@ -196,6 +181,7 @@ module DaggerRuby
196
181
  def with_mounted_directory(path, source, opts = {})
197
182
  args = { "path" => path, "source" => source.is_a?(DaggerObject) ? source.id : source }
198
183
  args["owner"] = opts[:owner] if opts[:owner]
184
+ args["readOnly"] = opts[:read_only] if opts.key?(:read_only)
199
185
  args["expand"] = opts[:expand] if opts.key?(:expand)
200
186
 
201
187
  chain_operation("withMountedDirectory", args)
@@ -232,7 +218,7 @@ module DaggerRuby
232
218
 
233
219
  def without_exposed_port(port, opts = {})
234
220
  args = { "port" => port }
235
- args["protocol"] = opts[:protocol] if opts[:protocol]
221
+ args["protocol"] = QueryBuilder.enum_value(opts[:protocol]) if opts[:protocol]
236
222
 
237
223
  chain_operation("withoutExposedPort", args)
238
224
  end
@@ -274,23 +260,19 @@ module DaggerRuby
274
260
  end
275
261
 
276
262
  def env_variables
277
- get_scalar("envVariables")
263
+ get_selection("envVariables", "name value")
278
264
  end
279
265
 
280
266
  def env_variable(name)
281
- query = @query_builder.build_query_with_selection("envVariable(name: \"#{name}\")")
282
- result = @client.execute(query)
283
- extract_value_from_result(result, "envVariable")
267
+ get_scalar("envVariable", { "name" => name })
284
268
  end
285
269
 
286
270
  def labels
287
- get_scalar("labels")
271
+ get_selection("labels", "name value")
288
272
  end
289
273
 
290
274
  def label(name)
291
- query = @query_builder.build_query_with_selection("label(name: \"#{name}\")")
292
- result = @client.execute(query)
293
- extract_value_from_result(result, "label")
275
+ get_scalar("label", { "name" => name })
294
276
  end
295
277
 
296
278
  def mounts
@@ -298,7 +280,7 @@ module DaggerRuby
298
280
  end
299
281
 
300
282
  def exposed_ports
301
- get_scalar("exposedPorts")
283
+ get_selection("exposedPorts", "port protocol description experimentalSkipHealthcheck")
302
284
  end
303
285
 
304
286
  def platform
@@ -311,48 +293,41 @@ module DaggerRuby
311
293
 
312
294
  def export(path, opts = {})
313
295
  args = { "path" => path }
314
- args["platformVariants"] = opts[:platform_variants] if opts[:platform_variants]
315
- args["forcedCompression"] = opts[:forced_compression] if opts[:forced_compression]
316
- args["mediaTypes"] = opts[:media_types] if opts[:media_types]
296
+ args["platformVariants"] = graphql_ids(opts[:platform_variants]) if opts[:platform_variants]
297
+ args["forcedCompression"] = QueryBuilder.enum_value(opts[:forced_compression]) if opts[:forced_compression]
298
+ args["mediaTypes"] = QueryBuilder.enum_value(opts[:media_types]) if opts[:media_types]
317
299
  args["expand"] = opts[:expand] if opts.key?(:expand)
318
300
 
319
- query = @query_builder.build_query_with_selection("export(#{format_arguments(args)})")
320
- result = @client.execute(query)
321
- extract_value_from_result(result, "export")
301
+ get_scalar("export", args)
322
302
  end
323
303
 
324
304
  def export_to_file(path, opts = {})
325
- args = { "path" => path }
326
- args["platformVariants"] = opts[:platform_variants] if opts[:platform_variants]
327
- args["forcedCompression"] = opts[:forced_compression] if opts[:forced_compression]
328
- args["mediaTypes"] = opts[:media_types] if opts[:media_types]
329
- args["expand"] = opts[:expand] if opts.key?(:expand)
330
-
331
- query = @query_builder.build_query_with_selection("exportToFile(#{format_arguments(args)})")
332
- result = @client.execute(query)
333
- extract_value_from_result(result, "exportToFile")
305
+ export(path, opts)
334
306
  end
335
307
 
336
308
  def publish(address, opts = {})
337
309
  args = { "address" => address }
338
- args["platformVariants"] = opts[:platform_variants] if opts[:platform_variants]
339
- args["forcedCompression"] = opts[:forced_compression] if opts[:forced_compression]
340
- args["mediaTypes"] = opts[:media_types] if opts[:media_types]
341
-
342
- query = @query_builder.build_query_with_selection("publish(#{format_arguments(args)})")
343
- result = @client.execute(query)
344
- extract_value_from_result(result, "publish")
310
+ args["platformVariants"] = graphql_ids(opts[:platform_variants]) if opts[:platform_variants]
311
+ args["forcedCompression"] = QueryBuilder.enum_value(opts[:forced_compression]) if opts[:forced_compression]
312
+ args["mediaTypes"] = QueryBuilder.enum_value(opts[:media_types]) if opts[:media_types]
313
+
314
+ if opts[:registry_service]
315
+ args["registryService"] = if opts[:registry_service].is_a?(DaggerObject)
316
+ opts[:registry_service].id
317
+ else
318
+ opts[:registry_service]
319
+ end
320
+ end
321
+ get_scalar("publish", args)
345
322
  end
346
323
 
347
324
  def as_tarball(opts = {})
348
325
  args = {}
349
- args["platformVariants"] = opts[:platform_variants] if opts[:platform_variants]
350
- args["forcedCompression"] = opts[:forced_compression] if opts[:forced_compression]
351
- args["mediaTypes"] = opts[:media_types] if opts[:media_types]
326
+ args["platformVariants"] = graphql_ids(opts[:platform_variants]) if opts[:platform_variants]
327
+ args["forcedCompression"] = QueryBuilder.enum_value(opts[:forced_compression]) if opts[:forced_compression]
328
+ args["mediaTypes"] = QueryBuilder.enum_value(opts[:media_types]) if opts[:media_types]
352
329
 
353
- query = @query_builder.build_query_with_selection("asTarball(#{format_arguments(args)})")
354
- result = @client.execute(query)
355
- extract_value_from_result(result, "asTarball")
330
+ get_object("asTarball", File, args)
356
331
  end
357
332
 
358
333
  def sync
@@ -362,32 +337,8 @@ module DaggerRuby
362
337
 
363
338
  private
364
339
 
365
- def format_arguments(args)
366
- return "" if args.empty?
367
-
368
- args.map { |key, value| "#{key}: #{format_value(value)}" }.join(", ")
369
- end
370
-
371
- def format_value(value)
372
- case value
373
- when String
374
- "\"#{value}\""
375
- when Integer, Float
376
- value.to_s
377
- when TrueClass, FalseClass
378
- value.to_s
379
- when NilClass
380
- "null"
381
- when Array
382
- "[#{value.map { |v| format_value(v) }.join(", ")}]"
383
- when Hash
384
- formatted_pairs = value.map { |k, v| "#{k}: #{format_value(v)}" }
385
- "{ #{formatted_pairs.join(", ")} }"
386
- when DaggerObject
387
- value.id
388
- else
389
- "\"#{value}\""
390
- end
340
+ def graphql_ids(values)
341
+ values.map { |value| value.is_a?(DaggerObject) ? value.id : value }
391
342
  end
392
343
  end
393
344
  end
@@ -23,8 +23,15 @@ module DaggerRuby
23
23
 
24
24
  protected
25
25
 
26
- def get_scalar(field)
27
- query = @query_builder.build_query_with_selection(field)
26
+ def get_scalar(field, args = {})
27
+ query = @query_builder.build_query_with_selection(field, args)
28
+ result = @client.execute_query(query)
29
+ extract_value_from_result(result, field)
30
+ end
31
+
32
+ def get_selection(field, selection, args = {})
33
+ selected_field = "#{QueryBuilder.new.field_selection(field, args)} { #{selection} }"
34
+ query = @query_builder.build_query_with_selection(selected_field)
28
35
  result = @client.execute_query(query)
29
36
  extract_value_from_result(result, field)
30
37
  end
@@ -52,42 +59,25 @@ module DaggerRuby
52
59
  klass.new(new_query, @client)
53
60
  end
54
61
 
55
- def get_object_array(field, klass, _args = {})
56
- query = @query_builder.build_query_with_selection(field)
57
-
58
- array_field = query.selections.find { |s| s.field == field }
59
- array_field&.select("id")
60
-
61
- result = @client.execute(query)
62
- ids = extract_array_from_result(result, field)
63
-
64
- ids.map { |id_data| klass.from_id(id_data["id"], @client) }
65
- end
66
-
67
- private
68
-
69
- def extract_array_from_result(result, field)
70
- current = result["data"]
71
-
72
- if @query_builder.root_field
73
- current = current[@query_builder.root_field]
74
- @query_builder.operation_chain.each do |operation|
75
- current = current[operation[:field]] if current
76
- end
77
- end
78
- current&.[](field) || []
62
+ def get_object_array(field, klass, args = {})
63
+ get_selection(field, "id", args).to_a.map { |data| klass.from_id(data.fetch("id"), @client) }
79
64
  end
80
65
 
81
66
  class << self
82
67
  def from_id(id, client)
83
- query = QueryBuilder.new(root_field_name)
84
- query.load_from_id(id)
68
+ query = QueryBuilder.new.chain_operation("load#{graphql_type_name}FromID", { "id" => id })
85
69
  new(query, client)
86
70
  end
87
71
 
88
72
  def root_field_name
89
73
  name.split("::").last.downcase
90
74
  end
75
+
76
+ private
77
+
78
+ def graphql_type_name
79
+ name.split("::").last
80
+ end
91
81
  end
92
82
  end
93
83
  end
@@ -4,12 +4,6 @@ require_relative "dagger_object"
4
4
 
5
5
  module DaggerRuby
6
6
  class Directory < DaggerObject
7
- def self.from_id(id, client)
8
- query = QueryBuilder.new("directory")
9
- query.load_from_id(id)
10
- new(query, client)
11
- end
12
-
13
7
  def self.root_field_name
14
8
  "directory"
15
9
  end
@@ -32,6 +26,9 @@ module DaggerRuby
32
26
  args = { "path" => path, "source" => directory.is_a?(DaggerObject) ? directory.id : directory }
33
27
  args["exclude"] = opts[:exclude] if opts[:exclude]
34
28
  args["include"] = opts[:include] if opts[:include]
29
+ args["gitignore"] = opts[:gitignore] if opts[:gitignore]
30
+ args["owner"] = opts[:owner] if opts[:owner]
31
+ args["permissions"] = opts[:permissions] if opts[:permissions]
35
32
 
36
33
  chain_operation("withDirectory", args)
37
34
  end
@@ -55,6 +52,14 @@ module DaggerRuby
55
52
  chain_operation("diff", { "other" => other.is_a?(DaggerObject) ? other.id : other })
56
53
  end
57
54
 
55
+ def filter(opts = {})
56
+ args = {}
57
+ args["exclude"] = opts[:exclude] if opts[:exclude]
58
+ args["include"] = opts[:include] if opts[:include]
59
+ args["gitignore"] = opts[:gitignore] if opts[:gitignore]
60
+ chain_operation("filter", args)
61
+ end
62
+
58
63
  def sync
59
64
  get_scalar("id")
60
65
  self
@@ -68,42 +73,30 @@ module DaggerRuby
68
73
  get_object("directory", Directory, { "path" => path })
69
74
  end
70
75
 
71
- def as_tarball(opts = {})
72
- args = {}
73
- args["forcedCompression"] = opts[:forced_compression] if opts[:forced_compression]
74
-
75
- get_object("asTarball", File, args)
76
- end
77
-
78
76
  def export(path, opts = {})
79
77
  args = { "path" => path }
80
- args["allowParentDirPath"] = opts[:allow_parent_dir_path] if opts.key?(:allow_parent_dir_path)
81
-
82
- query = @query_builder.build_query_with_selection("export(#{format_arguments(args)})")
83
- result = @client.execute(query)
84
- extract_value_from_result(result, "export")
78
+ args["wipe"] = opts[:wipe] if opts.key?(:wipe)
79
+ get_scalar("export", args)
85
80
  end
86
81
 
87
82
  def entries(path = ".")
88
- query = @query_builder.build_query_with_selection("entries(path: \"#{path}\")")
89
- result = @client.execute(query)
90
- extract_value_from_result(result, "entries")
83
+ get_scalar("entries", { "path" => path })
91
84
  end
92
85
 
93
86
  def glob(pattern)
94
- query = @query_builder.build_query_with_selection("glob(pattern: \"#{pattern}\")")
95
- result = @client.execute(query)
96
- extract_value_from_result(result, "glob")
87
+ get_scalar("glob", { "pattern" => pattern })
97
88
  end
98
89
 
99
90
  def docker_build(opts = {})
100
- args = {}
101
- args["dockerfile"] = opts[:dockerfile] if opts[:dockerfile]
102
- args["platform"] = opts[:platform] if opts[:platform]
103
- args["buildArgs"] = opts[:build_args] if opts[:build_args]
104
- args["target"] = opts[:target] if opts[:target]
91
+ args = {
92
+ "dockerfile" => opts[:dockerfile],
93
+ "platform" => opts[:platform],
94
+ "buildArgs" => opts[:build_args],
95
+ "target" => opts[:target],
96
+ }.compact
105
97
  args["secrets"] = opts[:secrets].map { |s| s.is_a?(DaggerObject) ? s.id : s } if opts[:secrets]
106
98
  args["noInit"] = opts[:no_init] if opts.key?(:no_init)
99
+ args["ssh"] = opts[:ssh].is_a?(DaggerObject) ? opts[:ssh].id : opts[:ssh] if opts[:ssh]
107
100
 
108
101
  require_relative "container" unless defined?(Container)
109
102
  get_object("dockerBuild", Container, args)
@@ -129,7 +122,7 @@ module DaggerRuby
129
122
  end
130
123
  end
131
124
 
132
- def self.load_from_host(path, opts = {}, client)
125
+ def self.load_from_host(path, client, opts = {})
133
126
  args = { "path" => path }
134
127
  args["exclude"] = opts[:exclude] if opts[:exclude]
135
128
  args["include"] = opts[:include] if opts[:include]
@@ -138,35 +131,5 @@ module DaggerRuby
138
131
  host_dir_query = host_query.chain_operation("directory", args)
139
132
  Directory.new(host_dir_query, client)
140
133
  end
141
-
142
- private
143
-
144
- def format_arguments(args)
145
- return "" if args.empty?
146
-
147
- args.map { |key, value| "#{key}: #{format_value(value)}" }.join(", ")
148
- end
149
-
150
- def format_value(value)
151
- case value
152
- when String
153
- "\"#{value}\""
154
- when Integer, Float
155
- value.to_s
156
- when TrueClass, FalseClass
157
- value.to_s
158
- when NilClass
159
- "null"
160
- when Array
161
- "[#{value.map { |v| format_value(v) }.join(", ")}]"
162
- when Hash
163
- formatted_pairs = value.map { |k, v| "#{k}: #{format_value(v)}" }
164
- "{ #{formatted_pairs.join(", ")} }"
165
- when DaggerObject
166
- value.id
167
- else
168
- "\"#{value}\""
169
- end
170
- end
171
134
  end
172
135
  end