emerge 0.2.1 → 0.2.2

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: f4bfa9e9a7d920f4f41ca06eef1283b73be375bffda3d414c27b55eeb11c1cef
4
- data.tar.gz: ed994835ee23a65f5ccfbec7acc84114f363f82f2464b4147939bb32b2664c3f
3
+ metadata.gz: 4a44399f9df18a4ce4d32984e12eaadb2fa921c34409d8e4daa0dd1b4acddd2c
4
+ data.tar.gz: 855d965c1478cbc23eee27f5f99281d1a144b7c40197bdb693fac7d93f0be72d
5
5
  SHA512:
6
- metadata.gz: de61137a2b6d33d3c6e3e8f8ab63b705658098d42c613a991f69102f01b93d3b374010939c087af06c8becfd20cb77c1f4279092ff5dc12556d803b607698a30
7
- data.tar.gz: bde1f8a729fd46b45600e8fcc50921399e334c1bf50b071c222bac4c81050a200819baeb643fbbab91fa1ef13c9b9dc5123258416e1c88fe2fd9cd284efb58f0
6
+ metadata.gz: 9d005834cf05f3d463df75af935e5e5ad075fe98cac3a05169df0e9f29c50366731f99b606af924ec33afce6fe332cd0e0ebccdd4768d52fa2dff59628e28b68
7
+ data.tar.gz: 184aad1844eacdf8aa3693ab5ff45acb36f11a16d039f258137f807f355f822b5f31565450927f5b6db453300785df287dcb5dc7c68227d635ccc7dc498a83ba
data/README.md CHANGED
@@ -14,7 +14,7 @@ gem install emerge
14
14
 
15
15
  ## API Key
16
16
 
17
- Follow our guide to obtain an [API key](https://docs.emergetools.com/docs/uploading-basics#obtain-an-api-key) for your organization. The API Token is used by the CLI to authenticate with the Emerge API. The CLI will automatically pick up the API key if configured as an `EMERGE_API_TOKEN` environment variable, or you can manually pass it into individual commands.
17
+ Follow our guide to obtain an [API key](https://docs.emergetools.com/docs/uploading-basics#obtain-an-api-key) for your organization. The API Token is used by the CLI to authenticate with the Emerge API. The CLI will automatically pick up the API key if configured as an `EMERGE_API_TOKEN` environment variable, or you can manually pass it into individual commands with the `--api-token` option.
18
18
 
19
19
  ## Snapshots
20
20
 
@@ -92,3 +92,24 @@ emerge upload snapshots \
92
92
  --client-library paparazzi \
93
93
  --project-root /my/awesomeapp/android/repo
94
94
  ```
95
+
96
+ ### Using with Roborazzi
97
+
98
+ Snapshots generated via [Roborazzi](https://github.com/takahirom/roborazzi) are natively supported by the CLI by setting `--client-library roborazzi` and a `--project-root` directory. This will scan your project for all images found in `**/build/outputs/roborazzi` directories.
99
+
100
+ Example:
101
+
102
+ ```shell
103
+ emerge upload snapshots \
104
+ --name "AwesomeApp Roborazzi" \
105
+ --id "com.emerge.awesomeapp.roborazzi" \
106
+ --repo-name "EmergeTools/AwesomeApp" \
107
+ --client-library roborazzi \
108
+ --project-root /my/awesomeapp/android/repo
109
+ ```
110
+
111
+ ## Building
112
+
113
+ This depends on [Tree Sitter](https://tree-sitter.github.io/tree-sitter/) for part of its functionality.
114
+
115
+ In order to parse language grammars for Swift and Kotlin, both of which are third-party language grammars, we also depend on [tsdl](https://github.com/stackmystack/tsdl). This downloads and compiles the language grammars into dylibs for us to use.
@@ -18,8 +18,6 @@ module EmergeCLI
18
18
  ORDER_FILE = 'ORDER_FILE'.freeze
19
19
  ORDER_FILE_PATH = '$(PROJECT_DIR)/orderfiles/orderfile.txt'.freeze
20
20
 
21
- def initialize; end
22
-
23
21
  def call(**options)
24
22
  @options = options
25
23
  before(options)
@@ -39,8 +39,6 @@ module EmergeCLI
39
39
  format KEY=VALUE".freeze
40
40
  AVAILABLE_OS_VERSIONS = ['17.2', '17.5', '18.0'].freeze
41
41
 
42
- def initialize; end
43
-
44
42
  def call(**options)
45
43
  @options = options
46
44
  before(options)
@@ -204,12 +202,11 @@ format KEY=VALUE".freeze
204
202
  end
205
203
 
206
204
  def get_parsed_previews(previews_exact, previews_regex)
207
- excluded = []
208
- previews_exact.each do |preview|
209
- excluded.push({
210
- 'type' => 'exact',
211
- 'value' => preview
212
- })
205
+ excluded = previews_exact.map do |preview|
206
+ {
207
+ 'type' => 'exact',
208
+ 'value' => preview
209
+ }
213
210
  end
214
211
  previews_regex.each do |preview|
215
212
  excluded.push({
@@ -80,7 +80,7 @@ module EmergeCLI
80
80
 
81
81
  # Add app_size lane if not present
82
82
  unless current_content.match?(/^\s*lane\s*:app_size\s*do/)
83
- app_size_lane = <<~'RUBY'.gsub(/^/, ' ')
83
+ app_size_lane = <<~RUBY.gsub(/^/, ' ')
84
84
  lane :app_size do
85
85
  # NOTE: If you already have a lane setup to build your app, then you can that instead of this and call emerge() after it.
86
86
  build_app(scheme: ENV["SCHEME_NAME"], export_method: "development")
@@ -92,7 +92,7 @@ module EmergeCLI
92
92
 
93
93
  # Add snapshots lane if not present
94
94
  unless current_content.match?(/^\s*lane\s*:build_upload_emerge_snapshot\s*do/)
95
- snapshot_lane = <<~'RUBY'.gsub(/^/, ' ')
95
+ snapshot_lane = <<~RUBY.gsub(/^/, ' ')
96
96
  desc 'Build and upload snapshot build to Emerge Tools'
97
97
  lane :build_upload_emerge_snapshot do
98
98
  emerge_snapshot(scheme: ENV["SCHEME_NAME"])
@@ -51,8 +51,8 @@ module EmergeCLI
51
51
  success = false
52
52
 
53
53
  begin
54
- api_token = @options[:api_token] || ENV['EMERGE_API_TOKEN']
55
- raise 'API token is required' unless api_token
54
+ api_token = @options[:api_token] || ENV.fetch('EMERGE_API_TOKEN', nil)
55
+ raise 'API token is required and cannot be blank' if api_token.nil? || api_token.strip.empty?
56
56
 
57
57
  @network ||= EmergeCLI::Network.new(api_token:)
58
58
  @git_info_provider ||= GitInfoProvider.new
@@ -133,8 +133,8 @@ module EmergeCLI
133
133
 
134
134
  if seen_files[file_name]
135
135
  Logger.warn "Duplicate file name detected: '#{file_name}'. " \
136
- "Previous occurrence: '#{seen_files[file_name]}'. " \
137
- 'This upload will overwrite the previous one.'
136
+ "Previous occurrence: '#{seen_files[file_name]}'. " \
137
+ 'This upload will overwrite the previous one.'
138
138
  end
139
139
  seen_files[file_name] = image_path
140
140
  end
data/lib/emerge_cli.rb CHANGED
@@ -1,23 +1,29 @@
1
- require_relative './commands/global_options'
2
- require_relative './commands/upload/snapshots/snapshots'
3
- require_relative './commands/upload/snapshots/client_libraries/swift_snapshot_testing'
4
- require_relative './commands/upload/snapshots/client_libraries/paparazzi'
5
- require_relative './commands/upload/snapshots/client_libraries/roborazzi'
6
- require_relative './commands/upload/snapshots/client_libraries/default'
7
- require_relative './commands/integrate/fastlane'
8
- require_relative './commands/config/snapshots/snapshots_ios'
9
- require_relative './commands/config/orderfiles/orderfiles_ios'
10
-
11
- require_relative './utils/git_info_provider'
12
- require_relative './utils/git_result'
13
- require_relative './utils/github'
14
- require_relative './utils/git'
15
- require_relative './utils/logger'
16
- require_relative './utils/network'
17
- require_relative './utils/profiler'
18
- require_relative './utils/project_detector'
1
+ require_relative 'version'
2
+
3
+ require_relative 'commands/global_options'
4
+ require_relative 'commands/upload/snapshots/snapshots'
5
+ require_relative 'commands/upload/snapshots/client_libraries/swift_snapshot_testing'
6
+ require_relative 'commands/upload/snapshots/client_libraries/paparazzi'
7
+ require_relative 'commands/upload/snapshots/client_libraries/roborazzi'
8
+ require_relative 'commands/upload/snapshots/client_libraries/default'
9
+ require_relative 'commands/integrate/fastlane'
10
+ require_relative 'commands/config/snapshots/snapshots_ios'
11
+ require_relative 'commands/config/orderfiles/orderfiles_ios'
12
+
13
+ require_relative 'reaper/ast_parser'
14
+
15
+ require_relative 'utils/git_info_provider'
16
+ require_relative 'utils/git_result'
17
+ require_relative 'utils/github'
18
+ require_relative 'utils/git'
19
+ require_relative 'utils/logger'
20
+ require_relative 'utils/network'
21
+ require_relative 'utils/profiler'
22
+ require_relative 'utils/project_detector'
19
23
 
20
24
  require 'dry/cli'
25
+ require 'pry'
26
+ require 'pry-byebug'
21
27
 
22
28
  module EmergeCLI
23
29
  extend Dry::CLI::Registry
@@ -37,4 +43,4 @@ module EmergeCLI
37
43
  end
38
44
 
39
45
  # By default the log level is INFO, but can be overridden by the --debug flag
40
- EmergeCLI::Logger.configure(::Logger::INFO)
46
+ EmergeCLI::Logger.configure(Logger::INFO)
@@ -0,0 +1,234 @@
1
+ require 'tree_sitter'
2
+
3
+ module Emerge
4
+ module Reaper
5
+ # Parses the AST of a given file using Tree Sitter and allows us to find usages or delete types.
6
+ # This does have a lot of limitations since it only looks at a single file at a time,
7
+ # but can get us most of the way there.
8
+ class AstParser
9
+ DECLARATION_NODE_TYPES = {
10
+ 'swift' => %i[class_declaration protocol_declaration],
11
+ 'kotlin' => %i[class_declaration protocol_declaration interface_declaration],
12
+ 'java' => %i[class_declaration protocol_declaration interface_declaration]
13
+ }.freeze
14
+
15
+ IDENTIFIER_NODE_TYPES = {
16
+ 'swift' => %i[simple_identifier qualified_name identifier type_identifier],
17
+ 'kotlin' => %i[simple_identifier qualified_name identifier type_identifier],
18
+ 'java' => %i[simple_identifier qualified_name identifier type_identifier]
19
+ }.freeze
20
+
21
+ COMMENT_AND_IMPORT_NODE_TYPES = {
22
+ 'swift' => %i[comment import_declaration],
23
+ 'kotlin' => %i[comment import_header],
24
+ 'java' => %i[comment import_declaration]
25
+ }.freeze
26
+
27
+ attr_reader :parser, :language
28
+
29
+ def initialize(language)
30
+ @parser = TreeSitter::Parser.new
31
+ @language = language
32
+ @current_file_contents = nil
33
+
34
+ platform = case RUBY_PLATFORM
35
+ when /darwin/
36
+ 'darwin'
37
+ when /linux/
38
+ 'linux'
39
+ else
40
+ raise "Unsupported platform: #{RUBY_PLATFORM}"
41
+ end
42
+
43
+ arch = case RUBY_PLATFORM
44
+ when /x86_64|amd64/
45
+ 'x86_64'
46
+ when /arm64|aarch64/
47
+ 'arm64'
48
+ else
49
+ raise "Unsupported architecture: #{RUBY_PLATFORM}"
50
+ end
51
+
52
+ extension = platform == 'darwin' ? 'dylib' : 'so'
53
+ parser_file = "libtree-sitter-#{language}-#{platform}-#{arch}.#{extension}"
54
+ parser_path = File.join('parsers', parser_file)
55
+
56
+ case language
57
+ when 'swift'
58
+ @parser.language = TreeSitter::Language.load('swift', parser_path)
59
+ when 'kotlin'
60
+ @parser.language = TreeSitter::Language.load('kotlin', parser_path)
61
+ when 'java'
62
+ @parser.language = TreeSitter::Language.load('java', parser_path)
63
+ else
64
+ raise "Unsupported language: #{language}"
65
+ end
66
+ end
67
+
68
+ # Deletes a type from the given file contents.
69
+ # Returns the modified file contents if successful, otherwise nil.
70
+ # TODO(telkins): Look into the tree-sitter query API to see if it simplifies this.
71
+ def delete_type(file_contents:, type_name:)
72
+ @current_file_contents = file_contents
73
+ tree = @parser.parse_string(nil, file_contents)
74
+ cursor = TreeSitter::TreeCursor.new(tree.root_node)
75
+ nodes_to_process = [cursor.current_node]
76
+ lines_to_remove = []
77
+
78
+ while (node = nodes_to_process.shift)
79
+ if declaration_node_types.include?(node.type)
80
+ type_identifier_node = find_type_identifier(node)
81
+ if type_identifier_node && fully_qualified_type_name(type_identifier_node) == type_name
82
+ remove_node(node, lines_to_remove)
83
+ end
84
+ end
85
+
86
+ if extension?(node)
87
+ user_type_nodes = node.select { |n| n.type == :user_type }
88
+ if user_type_nodes.length >= 1 && fully_qualified_type_name(user_type_nodes[0]) == type_name
89
+ remove_node(node, lines_to_remove)
90
+ end
91
+ end
92
+
93
+ node.each_named { |child| nodes_to_process.push(child) }
94
+ end
95
+
96
+ lines = file_contents.split("\n")
97
+ lines_to_remove.each do |range|
98
+ (range[:start]..range[:end]).each { |i| lines[i] = nil }
99
+
100
+ # Remove extra newline after class declaration, but only if it's blank
101
+ if range[:end] + 1 < lines.length && !lines[range[:end] + 1].nil? && lines[range[:end] + 1].match?(/^\s*$/)
102
+ lines[range[:end] + 1] = nil
103
+ end
104
+ end
105
+
106
+ modified_source = lines.compact.join("\n")
107
+ new_tree = @parser.parse_string(nil, modified_source)
108
+
109
+ return nil if only_comments_and_imports?(TreeSitter::TreeCursor.new(new_tree.root_node))
110
+ modified_source
111
+ end
112
+
113
+ # Finds all usages of a given type in a file.
114
+ # TODO(telkins): Look into the tree-sitter query API to see if it simplifies this.
115
+ def find_usages(file_contents:, type_name:)
116
+ @current_file_contents = file_contents
117
+ tree = @parser.parse_string(nil, file_contents)
118
+ cursor = TreeSitter::TreeCursor.new(tree.root_node)
119
+ usages = []
120
+ nodes_to_process = [cursor.current_node]
121
+
122
+ while (node = nodes_to_process.shift)
123
+ identifier_type = identifier_node_types.include?(node.type)
124
+ declaration_type = if node == tree.root_node
125
+ false
126
+ else
127
+ declaration_node_types.include?(node.parent&.type)
128
+ end
129
+ if declaration_type && fully_qualified_type_name(node) == type_name
130
+ usages << { line: node.start_point.row, usage_type: 'declaration' }
131
+ elsif identifier_type && node_text(node) == type_name
132
+ usages << { line: node.start_point.row, usage_type: 'identifier' }
133
+ end
134
+
135
+ node.each { |child| nodes_to_process.push(child) }
136
+ end
137
+
138
+ usages
139
+ end
140
+
141
+ private
142
+
143
+ def remove_node(node, lines_to_remove)
144
+ start_position = node.start_point.row
145
+ end_position = node.end_point.row
146
+ lines_to_remove << { start: start_position, end: end_position }
147
+
148
+ # Remove comments preceding the class declaration
149
+ predecessor = node.prev_named_sibling
150
+ return unless predecessor && predecessor.type == :comment
151
+ lines_to_remove << { start: predecessor.start_point.row, end: predecessor.end_point.row }
152
+ end
153
+
154
+ def extension?(node)
155
+ if node.type == :class_declaration
156
+ !node.find { |n| n.type == :extension }.nil?
157
+ else
158
+ false
159
+ end
160
+ end
161
+
162
+ def only_comments_and_imports?(root)
163
+ types = comment_and_import_types
164
+ root.current_node.all? do |child|
165
+ types.include?(child.type)
166
+ end
167
+ end
168
+
169
+ # Reaper expects a fully qualified type name, so we need to extract it from the AST.
170
+ # E.g. `MyModule.MyClass`
171
+ def fully_qualified_type_name(node)
172
+ class_name = node_text(node)
173
+ current_node = node
174
+ parent = find_parent_type_declaration(current_node)
175
+
176
+ while parent
177
+ type_identifier = find_type_identifier(parent)
178
+ user_type = find_user_type(parent)
179
+
180
+ if type_identifier && type_identifier != current_node
181
+ class_name = "#{node_text(type_identifier)}.#{class_name}"
182
+ current_node = type_identifier
183
+ elsif user_type && user_type != current_node
184
+ class_name = "#{node_text(user_type)}.#{class_name}"
185
+ current_node = user_type
186
+ end
187
+
188
+ parent = find_parent_type_declaration(parent)
189
+ end
190
+
191
+ class_name
192
+ end
193
+
194
+ def find_parent_type_declaration(node)
195
+ return nil unless node&.parent
196
+
197
+ current = node.parent
198
+ while current && !current.null?
199
+ return current if current.type && declaration_node_types.include?(current.type)
200
+ break unless current.parent && !current.parent.null?
201
+ current = current.parent
202
+ end
203
+ nil
204
+ end
205
+
206
+ def find_type_identifier(node)
207
+ node.find { |n| identifier_node_types.include?(n.type) }
208
+ end
209
+
210
+ def find_user_type(node)
211
+ node.find { |n| n.type == :user_type }
212
+ end
213
+
214
+ def declaration_node_types
215
+ DECLARATION_NODE_TYPES[language]
216
+ end
217
+
218
+ def identifier_node_types
219
+ IDENTIFIER_NODE_TYPES[language]
220
+ end
221
+
222
+ def comment_and_import_types
223
+ COMMENT_AND_IMPORT_NODE_TYPES[language]
224
+ end
225
+
226
+ def node_text(node)
227
+ return '' unless @current_file_contents
228
+ start_byte = node.start_byte
229
+ end_byte = node.end_byte
230
+ @current_file_contents[start_byte...end_byte]
231
+ end
232
+ end
233
+ end
234
+ end
data/lib/utils/git.rb CHANGED
@@ -81,7 +81,7 @@ module EmergeCLI
81
81
  .split("\n")
82
82
  .map(&:strip)
83
83
  .find { |line| line.start_with?('HEAD branch: ') }
84
- &.split(' ')
84
+ &.split
85
85
  &.last
86
86
  end
87
87
 
data/lib/utils/github.rb CHANGED
@@ -4,7 +4,7 @@ module EmergeCLI
4
4
  GITHUB_EVENT_PUSH = 'push'.freeze
5
5
 
6
6
  def self.event_name
7
- ENV['GITHUB_EVENT_NAME']
7
+ ENV.fetch('GITHUB_EVENT_NAME', nil)
8
8
  end
9
9
 
10
10
  def self.supported_github_event?
@@ -22,7 +22,7 @@ module EmergeCLI
22
22
 
23
23
  def self.sha
24
24
  if push?
25
- ENV['GITHUB_SHA']
25
+ ENV.fetch('GITHUB_SHA', nil)
26
26
  elsif pull_request?
27
27
  github_event_data.dig(:pull_request, :head, :sha)
28
28
  end
@@ -55,7 +55,7 @@ module EmergeCLI
55
55
 
56
56
  def self.github_event_data
57
57
  @github_event_data ||= begin
58
- github_event_path = ENV['GITHUB_EVENT_PATH']
58
+ github_event_path = ENV.fetch('GITHUB_EVENT_PATH', nil)
59
59
  Logger.error 'GITHUB_EVENT_PATH is not set' if github_event_path.nil?
60
60
 
61
61
  Logger.error "File #{github_event_path} doesn't exist" unless File.exist?(github_event_path)
data/lib/utils/logger.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'logger'
2
- require 'colorize'
2
+ require 'colored2'
3
3
 
4
4
  module EmergeCLI
5
5
  class Logger
@@ -43,7 +43,7 @@ module EmergeCLI
43
43
  when 'ERROR'
44
44
  msg.to_s.red
45
45
  when 'DEBUG'
46
- msg.to_s.light_blue
46
+ msg.to_s.blue
47
47
  else
48
48
  msg.to_s
49
49
  end
data/lib/utils/network.rb CHANGED
@@ -9,7 +9,7 @@ module EmergeCLI
9
9
  public_constant :EMERGE_API_PROD_URL
10
10
 
11
11
  RETRY_DELAY = 5
12
- MAX_RETRIES = 1
12
+ MAX_RETRIES = 3
13
13
 
14
14
  def initialize(api_token:, base_url: EMERGE_API_PROD_URL)
15
15
  @base_url = base_url
@@ -43,7 +43,10 @@ module EmergeCLI
43
43
  end
44
44
  absolute_uri = uri.to_s
45
45
 
46
- headers = { 'X-API-Token' => @api_token }
46
+ headers = {
47
+ 'X-API-Token' => @api_token,
48
+ 'User-Agent' => "emerge-cli/#{EmergeCLI::VERSION}"
49
+ }
47
50
  headers['Content-Type'] = 'application/json' if method == :post && body.is_a?(Hash)
48
51
  headers.merge!(custom_headers)
49
52
 
@@ -62,20 +65,32 @@ module EmergeCLI
62
65
 
63
66
  response
64
67
  rescue StandardError => e
65
- # Workaround for an issue where the request is not fully written, haven't determined the root cause yet
66
- if e.message.include?('Wrote 0 bytes') && retries < MAX_RETRIES
67
- retries += 1
68
- Logger.warn "Request failed due to incomplete write. Retrying in #{RETRY_DELAY} seconds..."
69
- sleep RETRY_DELAY
68
+ retries += 1
69
+ if retries <= MAX_RETRIES
70
+ delay = RETRY_DELAY * retries
71
+ error_message = e.message
72
+ Logger.warn "Request failed (attempt #{retries}/#{MAX_RETRIES}): #{error_message}"
73
+ Logger.warn "Retrying in #{delay} seconds..."
74
+
75
+ begin
76
+ @internet.close
77
+ rescue StandardError
78
+ nil
79
+ end
80
+ @internet = Async::HTTP::Internet.new
81
+
82
+ sleep delay
70
83
  retry
71
84
  else
72
- Logger.error "Request failed: #{absolute_uri} #{e.message}"
85
+ Logger.error "Request failed after #{MAX_RETRIES} attempts: #{absolute_uri} #{e.message}"
73
86
  raise e
74
87
  end
75
88
  end
76
89
  end
77
90
 
78
91
  def perform_request(method, absolute_uri, headers, body)
92
+ headers ||= {}
93
+
79
94
  case method
80
95
  when :get
81
96
  @internet.get(absolute_uri, headers:)
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module EmergeCli
2
- VERSION = '0.2.1'.freeze
1
+ module EmergeCLI
2
+ VERSION = '0.2.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emerge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emerge Tools
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-21 00:00:00.000000000 Z
11
+ date: 2024-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.20.0
19
+ version: 2.21.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.20.0
26
+ version: 2.21.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: async-http
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.83.1
33
+ version: 0.86.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.83.1
40
+ version: 0.86.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: chunky_png
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.4.0
55
- - !ruby/object:Gem::Dependency
56
- name: colorize
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 1.1.0
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 1.1.0
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: dry-cli
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -95,145 +81,75 @@ dependencies:
95
81
  - !ruby/object:Gem::Version
96
82
  version: 0.2.1
97
83
  - !ruby/object:Gem::Dependency
98
- name: tty-prompt
84
+ name: pry-byebug
99
85
  requirement: !ruby/object:Gem::Requirement
100
86
  requirements:
101
87
  - - "~>"
102
88
  - !ruby/object:Gem::Version
103
- version: 0.23.1
89
+ version: '3.8'
104
90
  type: :runtime
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
- version: 0.23.1
96
+ version: '3.8'
111
97
  - !ruby/object:Gem::Dependency
112
- name: tty-table
98
+ name: ruby_tree_sitter
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - "~>"
116
102
  - !ruby/object:Gem::Version
117
- version: 0.12.0
103
+ version: '1.9'
118
104
  type: :runtime
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - "~>"
123
109
  - !ruby/object:Gem::Version
124
- version: 0.12.0
110
+ version: '1.9'
125
111
  - !ruby/object:Gem::Dependency
126
- name: xcodeproj
112
+ name: tty-prompt
127
113
  requirement: !ruby/object:Gem::Requirement
128
114
  requirements:
129
115
  - - "~>"
130
116
  - !ruby/object:Gem::Version
131
- version: 1.27.0
117
+ version: 0.23.1
132
118
  type: :runtime
133
119
  prerelease: false
134
120
  version_requirements: !ruby/object:Gem::Requirement
135
121
  requirements:
136
122
  - - "~>"
137
123
  - !ruby/object:Gem::Version
138
- version: 1.27.0
139
- - !ruby/object:Gem::Dependency
140
- name: minitest
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 5.25.1
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: 5.25.1
153
- - !ruby/object:Gem::Dependency
154
- name: minitest-reporters
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: 1.7.1
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: 1.7.1
167
- - !ruby/object:Gem::Dependency
168
- name: pry
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: 0.15.0
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - "~>"
179
- - !ruby/object:Gem::Version
180
- version: 0.15.0
181
- - !ruby/object:Gem::Dependency
182
- name: rake
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: 13.2.1
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: 13.2.1
195
- - !ruby/object:Gem::Dependency
196
- name: rspec
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - "~>"
200
- - !ruby/object:Gem::Version
201
- version: 3.13.0
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - "~>"
207
- - !ruby/object:Gem::Version
208
- version: 3.13.0
124
+ version: 0.23.1
209
125
  - !ruby/object:Gem::Dependency
210
- name: rubocop
126
+ name: tty-table
211
127
  requirement: !ruby/object:Gem::Requirement
212
128
  requirements:
213
129
  - - "~>"
214
130
  - !ruby/object:Gem::Version
215
- version: 1.68.0
216
- type: :development
131
+ version: 0.12.0
132
+ type: :runtime
217
133
  prerelease: false
218
134
  version_requirements: !ruby/object:Gem::Requirement
219
135
  requirements:
220
136
  - - "~>"
221
137
  - !ruby/object:Gem::Version
222
- version: 1.68.0
138
+ version: 0.12.0
223
139
  - !ruby/object:Gem::Dependency
224
- name: simplecov
140
+ name: xcodeproj
225
141
  requirement: !ruby/object:Gem::Requirement
226
142
  requirements:
227
143
  - - "~>"
228
144
  - !ruby/object:Gem::Version
229
- version: 0.22.0
230
- type: :development
145
+ version: 1.27.0
146
+ type: :runtime
231
147
  prerelease: false
232
148
  version_requirements: !ruby/object:Gem::Requirement
233
149
  requirements:
234
150
  - - "~>"
235
151
  - !ruby/object:Gem::Version
236
- version: 0.22.0
152
+ version: 1.27.0
237
153
  description: The official CLI for Emerge Tools
238
154
  email:
239
155
  - support@emergetools.com
@@ -255,6 +171,7 @@ files:
255
171
  - lib/commands/upload/snapshots/client_libraries/swift_snapshot_testing.rb
256
172
  - lib/commands/upload/snapshots/snapshots.rb
257
173
  - lib/emerge_cli.rb
174
+ - lib/reaper/ast_parser.rb
258
175
  - lib/utils/git.rb
259
176
  - lib/utils/git_info_provider.rb
260
177
  - lib/utils/git_result.rb
@@ -271,6 +188,7 @@ metadata:
271
188
  homepage_uri: https://github.com/EmergeTools/emerge-cli
272
189
  source_code_uri: https://github.com/EmergeTools/emerge-cli
273
190
  changelog_uri: https://github.com/EmergeTools/emerge-cli/blob/main/CHANGELOG.md
191
+ rubygems_mfa_required: 'true'
274
192
  post_install_message:
275
193
  rdoc_options: []
276
194
  require_paths: