cogbox 0.190.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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +22 -0
  4. data/.ruby-version +1 -0
  5. data/CODE_OF_CONDUCT.md +132 -0
  6. data/LICENSE +190 -0
  7. data/README.md +184 -0
  8. data/Rakefile +12 -0
  9. data/lib/cogbox/code_interpreter.rb +360 -0
  10. data/lib/cogbox/cogbox.rb +337 -0
  11. data/lib/cogbox/common/charts.rb +125 -0
  12. data/lib/cogbox/common/code_interpreter.rb +57 -0
  13. data/lib/cogbox/common/code_language.rb +15 -0
  14. data/lib/cogbox/common/cogbox.rb +231 -0
  15. data/lib/cogbox/common/file_system.rb +27 -0
  16. data/lib/cogbox/common/git.rb +20 -0
  17. data/lib/cogbox/common/image.rb +501 -0
  18. data/lib/cogbox/common/process.rb +150 -0
  19. data/lib/cogbox/common/pty.rb +310 -0
  20. data/lib/cogbox/common/resources.rb +40 -0
  21. data/lib/cogbox/common/response.rb +84 -0
  22. data/lib/cogbox/common/snapshot.rb +125 -0
  23. data/lib/cogbox/computer_use.rb +920 -0
  24. data/lib/cogbox/config.rb +110 -0
  25. data/lib/cogbox/file_system.rb +452 -0
  26. data/lib/cogbox/file_transfer.rb +384 -0
  27. data/lib/cogbox/git.rb +335 -0
  28. data/lib/cogbox/lsp_server.rb +140 -0
  29. data/lib/cogbox/object_storage.rb +173 -0
  30. data/lib/cogbox/otel.rb +184 -0
  31. data/lib/cogbox/process.rb +551 -0
  32. data/lib/cogbox/sandbox.rb +752 -0
  33. data/lib/cogbox/sdk/version.rb +11 -0
  34. data/lib/cogbox/sdk.rb +57 -0
  35. data/lib/cogbox/snapshot_service.rb +239 -0
  36. data/lib/cogbox/util.rb +81 -0
  37. data/lib/cogbox/volume.rb +47 -0
  38. data/lib/cogbox/volume_service.rb +62 -0
  39. data/lib/cogbox.rb +11 -0
  40. data/project.json +100 -0
  41. data/scripts/generate-docs.rb +403 -0
  42. data/sig/cogbox/sdk.rbs +6 -0
  43. metadata +240 -0
@@ -0,0 +1,11 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # Copyright Cognifyi
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # frozen_string_literal: true
6
+
7
+ module Cogbox
8
+ module Sdk
9
+ VERSION = '0.190.1'
10
+ end
11
+ end
data/lib/cogbox/sdk.rb ADDED
@@ -0,0 +1,57 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # Copyright Cognifyi
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # frozen_string_literal: true
6
+
7
+ require 'logger'
8
+
9
+ require 'cogbox_api_client'
10
+ require 'cogbox_toolbox_api_client'
11
+ require 'toml'
12
+ require 'websocket-client-simple'
13
+
14
+ require_relative 'sdk/version'
15
+ require_relative 'config'
16
+ require_relative 'otel'
17
+ require_relative 'common/charts'
18
+ require_relative 'common/code_interpreter'
19
+ require_relative 'common/code_language'
20
+ require_relative 'common/cogbox'
21
+ require_relative 'common/file_system'
22
+ require_relative 'common/image'
23
+ require_relative 'common/git'
24
+ require_relative 'common/process'
25
+ require_relative 'common/pty'
26
+ require_relative 'common/resources'
27
+ require_relative 'common/response'
28
+ require_relative 'common/snapshot'
29
+ require_relative 'code_interpreter'
30
+ require_relative 'computer_use'
31
+ require_relative 'cogbox'
32
+ require_relative 'file_system'
33
+ require_relative 'git'
34
+ require_relative 'lsp_server'
35
+ require_relative 'object_storage'
36
+ require_relative 'sandbox'
37
+ require_relative 'snapshot_service'
38
+ require_relative 'util'
39
+ require_relative 'volume'
40
+ require_relative 'volume_service'
41
+ require_relative 'process'
42
+
43
+ module Cogbox
44
+ module Sdk
45
+ class Error < StandardError; end
46
+ class TimeoutError < Error; end
47
+ class AuthenticationError < Error; end
48
+ class ForbiddenError < Error; end
49
+ class NotFoundError < Error; end
50
+ class ConflictError < Error; end
51
+ class ValidationError < Error; end
52
+ class RateLimitError < Error; end
53
+ class ServerError < Error; end
54
+
55
+ def self.logger = @logger ||= Logger.new($stdout, level: Logger::INFO)
56
+ end
57
+ end
@@ -0,0 +1,239 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # Copyright Cognifyi
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # frozen_string_literal: true
6
+
7
+ require 'uri'
8
+
9
+ module Cogbox
10
+ class SnapshotService
11
+ include Instrumentation
12
+
13
+ SNAPSHOTS_FETCH_LIMIT = 200
14
+
15
+ # @param snapshots_api [CogboxApiClient::SnapshotsApi] The snapshots API client
16
+ # @param object_storage_api [CogboxApiClient::ObjectStorageApi] The object storage API client
17
+ # @param default_region_id [String, nil] Default region ID for snapshot creation
18
+ # @param otel_state [Cogbox::OtelState, nil]
19
+ def initialize(snapshots_api:, object_storage_api:, default_region_id: nil, otel_state: nil)
20
+ @snapshots_api = snapshots_api
21
+ @object_storage_api = object_storage_api
22
+ @default_region_id = default_region_id
23
+ @otel_state = otel_state
24
+ end
25
+
26
+ # List all Snapshots.
27
+ #
28
+ # @param page [Integer, Nil]
29
+ # @param limit [Integer, Nil]
30
+ # @return [Cogbox::PaginatedResource] Paginated list of all Snapshots
31
+ # @raise [Cogbox::Sdk::Error]
32
+ #
33
+ # @example
34
+ # cogbox = Cogbox::Cogbox.new
35
+ # response = cogbox.snapshot.list(page: 1, limit: 10)
36
+ # snapshots.items.each { |snapshot| puts "#{snapshot.name} (#{snapshot.image_name})" }
37
+ def list(page: nil, limit: nil)
38
+ raise Sdk::Error, 'page must be positive integer' if page && page < 1
39
+
40
+ raise Sdk::Error, 'limit must be positive integer' if limit && limit < 1
41
+
42
+ response = snapshots_api.get_all_snapshots(page:, limit:)
43
+ PaginatedResource.new(
44
+ total: response.total,
45
+ page: response.page,
46
+ total_pages: response.total_pages,
47
+ items: response.items.map { |snapshot_dto| Snapshot.from_dto(snapshot_dto) }
48
+ )
49
+ end
50
+
51
+ # Delete a Snapshot.
52
+ #
53
+ # @param snapshot [Cogbox::Snapshot] Snapshot to delete
54
+ # @return [void]
55
+ #
56
+ # @example
57
+ # cogbox = Cogbox::Cogbox.new
58
+ # snapshot = cogbox.snapshot.get("demo")
59
+ # cogbox.snapshot.delete(snapshot)
60
+ # puts "Snapshot deleted"
61
+ def delete(snapshot) = snapshots_api.remove_snapshot(snapshot.id)
62
+
63
+ # Get a Snapshot by name.
64
+ #
65
+ # @param name [String] Name of the Snapshot to get
66
+ # @return [Cogbox::Snapshot] The Snapshot object
67
+ #
68
+ # @example
69
+ # cogbox = Cogbox::Cogbox.new
70
+ # snapshot = cogbox.snapshot.get("demo")
71
+ # puts "#{snapshot.name} (#{snapshot.image_name})"
72
+ def get(name) = Snapshot.from_dto(snapshots_api.get_snapshot(name))
73
+
74
+ # Creates and registers a new snapshot from the given Image definition.
75
+ #
76
+ # @param params [Cogbox::CreateSnapshotParams] Parameters for snapshot creation
77
+ # @param on_logs [Proc, Nil] Callback proc handling snapshot creation logs
78
+ # @return [Cogbox::Snapshot] The created snapshot
79
+ #
80
+ # @example
81
+ # image = Image.debianSlim('3.12').pipInstall('numpy')
82
+ # params = CreateSnapshotParams.new(name: 'my-snapshot', image: image)
83
+ # snapshot = cogbox.snapshot.create(params) do |chunk|
84
+ # print chunk
85
+ # end
86
+ def create(params, on_logs: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
87
+ create_snapshot_req = CogboxApiClient::CreateSnapshot.new(name: params.name)
88
+
89
+ if params.image.is_a?(String)
90
+ create_snapshot_req.image_name = params.image
91
+ create_snapshot_req.entrypoint = params.entrypoint
92
+ else
93
+ create_snapshot_req.build_info = CogboxApiClient::CreateBuildInfo.new(
94
+ context_hashes: self.class.process_image_context(object_storage_api, params.image),
95
+ dockerfile_content: if params.entrypoint
96
+ params.image.entrypoint(params.entrypoint).dockerfile
97
+ else
98
+ params.image.dockerfile
99
+ end
100
+ )
101
+ end
102
+
103
+ if params.resources
104
+ create_snapshot_req.cpu = params.resources.cpu
105
+ create_snapshot_req.gpu = params.resources.gpu
106
+ if params.resources.gpu_type
107
+ create_snapshot_req.gpu_type =
108
+ params.resources.gpu_type.is_a?(Array) ? params.resources.gpu_type : [params.resources.gpu_type]
109
+ end
110
+ create_snapshot_req.memory = params.resources.memory
111
+ create_snapshot_req.disk = params.resources.disk
112
+ end
113
+
114
+ create_snapshot_req.region_id = params.region_id || @default_region_id
115
+ create_snapshot_req.sandbox_class = params.sandbox_class
116
+
117
+ snapshot = snapshots_api.create_snapshot(create_snapshot_req)
118
+
119
+ # Always wait for snapshot to be ready, regardless of on_logs
120
+ snapshot = wait_for_snapshot(snapshot, on_logs:)
121
+
122
+ if [CogboxApiClient::SnapshotState::ERROR, CogboxApiClient::SnapshotState::BUILD_FAILED].include?(snapshot.state)
123
+ raise Sdk::Error, "Failed to create snapshot #{snapshot.name}, reason: #{snapshot.error_reason}"
124
+ end
125
+
126
+ Snapshot.from_dto(snapshot)
127
+ end
128
+
129
+ # Activate a snapshot
130
+ #
131
+ # @param snapshot [Cogbox::Snapshot] The snapshot instance
132
+ # @return [Cogbox::Snapshot]
133
+ def activate(snapshot) = Snapshot.from_dto(snapshots_api.activate_snapshot(snapshot.id))
134
+
135
+ instrument :list, :delete, :get, :create, :activate, component: 'SnapshotService'
136
+
137
+ # Processes the image context by uploading it to object storage
138
+ #
139
+ # @param image [Cogbox::Image] The Image instance
140
+ # @return [Array<String>] List of context hashes stored in object storage
141
+ def self.process_image_context(object_storage_api, image) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
142
+ return [] unless image.context_list && !image.context_list.empty?
143
+
144
+ push_access_creds = object_storage_api.get_push_access
145
+
146
+ object_storage = ObjectStorage.new(
147
+ endpoint_url: push_access_creds.storage_url,
148
+ aws_access_key_id: push_access_creds.access_key,
149
+ aws_secret_access_key: push_access_creds.secret,
150
+ aws_session_token: push_access_creds.session_token,
151
+ bucket_name: push_access_creds.bucket
152
+ )
153
+
154
+ image.context_list.map do |context|
155
+ object_storage.upload(
156
+ context.source_path,
157
+ push_access_creds.organization_id,
158
+ context.archive_path
159
+ )
160
+ end
161
+ end
162
+
163
+ private
164
+
165
+ # @return [CogboxApiClient::SnapshotsApi] The snapshots API client
166
+ attr_reader :snapshots_api
167
+
168
+ # @return [CogboxApiClient::ObjectStorageApi, nil] The object storage API client
169
+ attr_reader :object_storage_api
170
+
171
+ # @return [String, nil] Default region ID for snapshot creation
172
+ attr_reader :default_region_id
173
+
174
+ # @return [Cogbox::OtelState, nil]
175
+ attr_reader :otel_state
176
+
177
+ # Wait for snapshot to reach a terminal state (ACTIVE, ERROR, or BUILD_FAILED)
178
+ # Optionally streams logs if on_logs callback is provided
179
+ #
180
+ # @param snapshot [CogboxApiClient::SnapshotDto]
181
+ # @param on_logs [Proc, nil]
182
+ # @return [CogboxApiClient::SnapshotDto]
183
+ def wait_for_snapshot(snapshot, on_logs:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
184
+ terminal_states = [
185
+ CogboxApiClient::SnapshotState::ACTIVE,
186
+ CogboxApiClient::SnapshotState::ERROR,
187
+ CogboxApiClient::SnapshotState::BUILD_FAILED
188
+ ]
189
+
190
+ thread = nil
191
+ previous_state = snapshot.state
192
+
193
+ # Log initial state if callback provided
194
+ on_logs&.call("Creating snapshot #{snapshot.name} (#{snapshot.state})")
195
+
196
+ until terminal_states.include?(snapshot.state)
197
+ Sdk.logger.debug("Waiting for snapshot to be created: #{snapshot.state}")
198
+
199
+ # Start log streaming thread if callback provided and snapshot is building
200
+ if on_logs && thread.nil? && snapshot.state != CogboxApiClient::SnapshotState::PENDING
201
+ thread = start_log_streaming(snapshot, on_logs:)
202
+ end
203
+
204
+ # Log state changes if callback provided
205
+ if on_logs && previous_state != snapshot.state
206
+ if snapshot.state != CogboxApiClient::SnapshotState::PENDING && thread.nil?
207
+ thread = start_log_streaming(snapshot, on_logs:)
208
+ end
209
+ on_logs.call("Creating snapshot #{snapshot.name} (#{snapshot.state})")
210
+ end
211
+
212
+ sleep(1)
213
+ previous_state = snapshot.state
214
+ snapshot = snapshots_api.get_snapshot(snapshot.id)
215
+ end
216
+
217
+ thread&.join
218
+
219
+ if on_logs && snapshot.state == CogboxApiClient::SnapshotState::ACTIVE
220
+ on_logs.call("Created snapshot #{snapshot.name} (#{snapshot.state})")
221
+ end
222
+
223
+ snapshot
224
+ end
225
+
226
+ # @param snapshot [CogboxApiClient::SnapshotDto]
227
+ # @param on_logs [Proc]
228
+ # @return [Thread]
229
+ def start_log_streaming(snapshot, on_logs:)
230
+ # Get build logs URL from API
231
+ build_logs_response = snapshots_api.get_snapshot_build_logs_url(snapshot.id)
232
+ uri = URI.parse("#{build_logs_response.url}?follow=true")
233
+
234
+ headers = {}
235
+ snapshots_api.api_client.update_params_for_auth!(headers, nil, ['bearer'])
236
+ Util.stream_async(uri:, headers:, on_chunk: on_logs)
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,81 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # Copyright Cognifyi
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # frozen_string_literal: true
6
+
7
+ require 'net/http'
8
+
9
+ module Cogbox
10
+ module Util
11
+ STDOUT_PREFIX = "\x01\x01\01"
12
+ private_constant :STDOUT_PREFIX
13
+
14
+ STDERR_PREFIX = "\x02\x02\02"
15
+ private_constant :STDERR_PREFIX
16
+
17
+ PREFIX_LEN = STDOUT_PREFIX.bytesize
18
+ private_constant :PREFIX_LEN
19
+
20
+ def self.demux(line)
21
+ out_parts = []
22
+ err_parts = []
23
+ state = nil
24
+ pos = 0
25
+
26
+ while pos < line.bytesize
27
+ si = line.index(STDOUT_PREFIX, pos)
28
+ ei = line.index(STDERR_PREFIX, pos)
29
+
30
+ if si && (ei.nil? || si < ei)
31
+ next_idx = si
32
+ next_state = :stdout
33
+ elsif ei
34
+ next_idx = ei
35
+ next_state = :stderr
36
+ else
37
+ case state
38
+ when :stdout then out_parts << line[pos..]
39
+ when :stderr then err_parts << line[pos..]
40
+ end
41
+ break
42
+ end
43
+
44
+ if pos < next_idx
45
+ chunk = line[pos...next_idx]
46
+ case state
47
+ when :stdout then out_parts << chunk
48
+ when :stderr then err_parts << chunk
49
+ end
50
+ end
51
+
52
+ state = next_state
53
+ pos = next_idx + PREFIX_LEN
54
+ end
55
+
56
+ [out_parts.join, err_parts.join]
57
+ end
58
+
59
+ # @param uri [URI]
60
+ # @param on_chunk [Proc]
61
+ # @param headers [Hash<String, String>]
62
+ # @return [Thread]
63
+ def self.stream_async(uri:, on_chunk:, headers: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
64
+ Sdk.logger.debug("Starting async stream: #{uri}")
65
+ Thread.new do
66
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
67
+ request = Net::HTTP::Get.new(uri, headers)
68
+
69
+ http.request(request) do |response|
70
+ response.read_body do |chunk|
71
+ Sdk.logger.debug("Chunked response received: #{chunk.inspect}")
72
+ on_chunk.call(chunk)
73
+ end
74
+ end
75
+ end
76
+ rescue Net::ReadTimeout => e
77
+ Sdk.logger.debug("Async stream (#{uri}) timeout: #{e.inspect}")
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # Copyright Cognifyi
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # frozen_string_literal: true
6
+
7
+ module Cogbox
8
+ class Volume
9
+ # @return [String]
10
+ attr_reader :id
11
+
12
+ # @return [String]
13
+ attr_reader :name
14
+
15
+ # @return [String]
16
+ attr_reader :organization_id
17
+
18
+ # @return [String]
19
+ attr_reader :state
20
+
21
+ # @return [String]
22
+ attr_reader :created_at
23
+
24
+ # @return [String]
25
+ attr_reader :updated_at
26
+
27
+ # @return [String]
28
+ attr_reader :last_used_at
29
+
30
+ # @return [String, nil]
31
+ attr_reader :error_reason
32
+
33
+ # Initialize volume from DTO
34
+ #
35
+ # @param volume_dto [CogboxApiClient::SandboxVolume]
36
+ def initialize(volume_dto)
37
+ @id = volume_dto.id
38
+ @name = volume_dto.name
39
+ @organization_id = volume_dto.organization_id
40
+ @state = volume_dto.state
41
+ @created_at = volume_dto.created_at
42
+ @updated_at = volume_dto.updated_at
43
+ @last_used_at = volume_dto.last_used_at
44
+ @error_reason = volume_dto.error_reason
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,62 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # Copyright Cognifyi
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # frozen_string_literal: true
6
+
7
+ module Cogbox
8
+ class VolumeService
9
+ include Instrumentation
10
+
11
+ # Service for managing Cogbox Volumes. Can be used to list, get, create and delete Volumes.
12
+ #
13
+ # @param volumes_api [CogboxApiClient::VolumesApi]
14
+ # @param otel_state [Cogbox::OtelState, nil]
15
+ def initialize(volumes_api, otel_state: nil)
16
+ @volumes_api = volumes_api
17
+ @otel_state = otel_state
18
+ end
19
+
20
+ # Create new Volume.
21
+ #
22
+ # @param name [String]
23
+ # @return [Cogbox::Volume]
24
+ def create(name) = Volume.new(volumes_api.create_volume(CogboxApiClient::CreateVolume.new(name:)))
25
+
26
+ # Delete a Volume.
27
+ #
28
+ # @param volume [Cogbox::Volume]
29
+ # @return [void]
30
+ def delete(volume) = volumes_api.delete_volume(volume.id)
31
+
32
+ # Get a Volume by name.
33
+ #
34
+ # @param name [String]
35
+ # @param create [Boolean]
36
+ # @return [Cogbox::Volume]
37
+ def get(name, create: false)
38
+ Volume.new(volumes_api.get_volume_by_name(name))
39
+ rescue CogboxApiClient::ApiError => e
40
+ raise unless create && e.code == 404 && e.message.include?("Volume with name #{name} not found")
41
+
42
+ create(name)
43
+ end
44
+
45
+ # List all Volumes.
46
+ #
47
+ # @return [Array<Cogbox::Volume>]
48
+ def list
49
+ volumes_api.list_volumes.map { |volume| Volume.new(volume) }
50
+ end
51
+
52
+ instrument :create, :delete, :get, :list, component: 'VolumeService'
53
+
54
+ private
55
+
56
+ # @return [CogboxApiClient::VolumesApi]
57
+ attr_reader :volumes_api
58
+
59
+ # @return [Cogbox::OtelState, nil]
60
+ attr_reader :otel_state
61
+ end
62
+ end
data/lib/cogbox.rb ADDED
@@ -0,0 +1,11 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # Copyright Cognifyi
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # frozen_string_literal: true
6
+
7
+ # Main entry point for the Cogbox Ruby SDK
8
+ # This file provides a convenient way to require the entire SDK with:
9
+ # require 'cogbox'
10
+
11
+ require_relative 'cogbox/sdk'
data/project.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "sdk-ruby",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "projectType": "library",
5
+ "sourceRoot": "libs/sdk-ruby",
6
+ "tags": [],
7
+ "targets": {
8
+ "build": {
9
+ "executor": "nx:run-commands",
10
+ "options": {
11
+ "cwd": "{projectRoot}",
12
+ "commands": ["rm -f *.gem", "bundle install", "gem build cogbox.gemspec"],
13
+ "parallel": false
14
+ },
15
+ "dependsOn": [
16
+ {
17
+ "target": "build",
18
+ "projects": ["api-client-ruby", "toolbox-api-client-ruby"]
19
+ },
20
+ "set-version"
21
+ ],
22
+ "outputs": ["{projectRoot}/**/*.gem"]
23
+ },
24
+ "set-version": {
25
+ "executor": "nx:run-commands",
26
+ "options": {
27
+ "cwd": "{projectRoot}",
28
+ "command": "if [ -n \"$RUBYGEMS_PKG_VERSION\" ]; then VER=\"${RUBYGEMS_PKG_VERSION#v}\"; sed -i \"s/VERSION = '[^']*'/VERSION = '$VER'/\" lib/cogbox/sdk/version.rb && echo \"Changed version to $VER\"; else echo \"Using version from version.rb\"; fi"
29
+ },
30
+ "cache": true,
31
+ "inputs": [
32
+ { "env": "RUBYGEMS_PKG_VERSION" },
33
+ { "env": "VERSION" }
34
+ ],
35
+ "outputs": ["{projectRoot}/lib/cogbox/sdk/version.rb"]
36
+ },
37
+ "lint": {
38
+ "executor": "nx:run-commands",
39
+ "options": {
40
+ "cwd": "{projectRoot}",
41
+ "command": "bundle exec rubocop"
42
+ }
43
+ },
44
+ "test": {
45
+ "executor": "nx:run-commands",
46
+ "cache": true,
47
+ "inputs": [
48
+ "default",
49
+ "{workspaceRoot}/libs/api-client-ruby/**/*",
50
+ "{workspaceRoot}/libs/toolbox-api-client-ruby/**/*"
51
+ ],
52
+ "outputs": [],
53
+ "options": {
54
+ "cwd": "{projectRoot}",
55
+ "command": "bundle exec rspec --format documentation --tag '~e2e'"
56
+ }
57
+ },
58
+ "test:e2e": {
59
+ "executor": "nx:run-commands",
60
+ "options": {
61
+ "cwd": "{projectRoot}",
62
+ "command": "bundle exec rspec spec/e2e_spec.rb --format documentation"
63
+ }
64
+ },
65
+ "format": {
66
+ "executor": "nx:run-commands",
67
+ "options": {
68
+ "cwd": "{projectRoot}",
69
+ "commands": ["bundle exec rubocop -a --fail-level=E"],
70
+ "parallel": false
71
+ }
72
+ },
73
+ "docs": {
74
+ "executor": "nx:run-commands",
75
+ "outputs": ["{workspaceRoot}/apps/docs/src/content/docs/en/ruby-sdk/**/*"],
76
+ "options": {
77
+ "cwd": "{projectRoot}",
78
+ "command": "bash -O extglob -c 'rm -rf ../../apps/docs/src/content/docs/en/ruby-sdk/!(index.mdx)' && bundle exec ruby scripts/generate-docs.rb"
79
+ }
80
+ },
81
+ "publish": {
82
+ "executor": "nx:run-commands",
83
+ "options": {
84
+ "cwd": "{projectRoot}",
85
+ "commands": [
86
+ "mkdir -p ~/.gem && echo \":rubygems: $RUBYGEMS_API_KEY\" > ~/.gem/credentials && chmod 0600 ~/.gem/credentials",
87
+ "VER=${RUBYGEMS_PKG_VERSION#v}; if [ -n \"$VER\" ] && gem list -r \"^cogbox$\" --version \"$VER\" 2>/dev/null | grep -q .; then echo \"cogbox==$VER already on RubyGems, skipping push\"; else gem push cogbox-*.gem --key rubygems --host https://rubygems.org; fi"
88
+ ],
89
+ "parallel": false
90
+ },
91
+ "dependsOn": [
92
+ {
93
+ "target": "publish",
94
+ "projects": ["api-client-ruby", "toolbox-api-client-ruby"]
95
+ },
96
+ "build"
97
+ ]
98
+ }
99
+ }
100
+ }