bundler-gem_bytes 0.1.0 → 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: cd1c19bddd6ef1887fcae3ed68a346395ba811b781e2c1321140015a1403e5d1
4
- data.tar.gz: d48849f9cf568c0dc3bd2f8b29cd8122b15993650d9bde3fbc41703931970fb7
3
+ metadata.gz: ad62897e0c19142e68da32d5cc2b63e1c2622beeaa9ecda235b48679f50ab3e2
4
+ data.tar.gz: e3a1340866ca56329fc9d03e4acae7dd1357ac288551ac6c196c79180d5818ff
5
5
  SHA512:
6
- metadata.gz: 9a42c3cee7bd326a9564144e2d6029a273be1676eece61bcb9fce50fac5b33e2939e328bef28a5121acdef69352f351c0c251ff16e36b918804b5c1d4935cdf4
7
- data.tar.gz: 95be78f3a9535dd2385425e231dae7de2e3bd4c186a9db24db53506eaae3843f293e89b6cf8c9642e14562f849060a1223f005e66286eeeabedc856df83afa83
6
+ metadata.gz: 64d2885ac473cea7a79cd7a48a04681ea9d60d0b3e027db73f64b622c827d49656aaf06c7c02b6f4bc46ff2c058b5b6b547f2545714a8d3886c55409a2b70f0e
7
+ data.tar.gz: 0f226e9914850042449dfd32b190f1f5f3b129ab16b334afa624489bf8633222ba18104017d4489fa820dcd12bb907ea3c89c8aeea80f7bc5a798d763e758fef
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.2"
3
+ }
data/CHANGELOG.md CHANGED
@@ -5,6 +5,44 @@ All notable changes to the process_executer gem will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.2](https://github.com/main-branch/bundler-gem_bytes/compare/v0.2.1...v0.2.2) (2025-04-16)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Automate commit-to-publish workflow version file path wrong ([4220bd4](https://github.com/main-branch/bundler-gem_bytes/commit/4220bd4428cc4841d56c65fb86540d9237b0944b))
14
+
15
+ ## [0.2.1](https://github.com/main-branch/bundler-gem_bytes/compare/v0.2.0...v0.2.1) (2025-04-16)
16
+
17
+
18
+ ### Features
19
+
20
+ * Add a gemspec action to make modification to a project gemspec ([d83d145](https://github.com/main-branch/bundler-gem_bytes/commit/d83d14598922fe8b54de12b92232e8cae6e6e668))
21
+ * Add the remove_dependency sub-action to the gemspec action ([ba1ff7b](https://github.com/main-branch/bundler-gem_bytes/commit/ba1ff7b8401ff7dd29c37f457da14452ce55c8f2))
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * Allow dependencies to have multiple version constraints ([4217151](https://github.com/main-branch/bundler-gem_bytes/commit/421715118af964e5e53ae35cda445e5b2dfd4f48))
27
+ * Automate commit-to-publish workflow ([3d018da](https://github.com/main-branch/bundler-gem_bytes/commit/3d018da4b2ac3caceaa81dd12a0b7771fc03db18))
28
+
29
+ ## v0.2.0 (2024-10-30)
30
+
31
+ [Full Changelog](https://github.com/main-branch/bundler-gem_bytes/compare/v0.1.0..v0.2.0)
32
+
33
+ Changes since v0.1.0:
34
+
35
+ * 96829fd docs: update the releasing guidelines
36
+ * 25c57f9 feat: make #remove_dependency available for gembytes scripts
37
+ * b285af5 docs: add development debugging instructions in the README.md
38
+ * ea05a44 fix: output an informative error when the gemspec parsed is not valid Ruby
39
+ * 2147776 test: add fully integrated test that installs and runs gembytes via bundler
40
+ * ab907b4 test: exclude lines from test coverage due to JRuby false positives
41
+ * 03692ad feat: make #add_dependency available for gembytes scripts
42
+ * 5d41e08 chore: add Bundler::GemBytes::Actions module to extend the API for gembytes scripts
43
+ * 6f7be90 chore: add class to upsert a gem dependency into a gemspec
44
+ * cf1ab4f chore: rake clobber should remove the .bundle directory
45
+
8
46
  ## v0.1.0 (2024-10-17)
9
47
 
10
48
  [Full Changelog](https://github.com/main-branch/bundler-gem_bytes/compare/ce13f25..v0.1.0)
data/README.md CHANGED
@@ -7,9 +7,6 @@ Version](https://badge.fury.io/rb/bundler-gem_bytes.svg)](https://badge.fury.io/
7
7
  Log](https://img.shields.io/badge/CHANGELOG-Latest-green)](https://rubydoc.info/gems/bundler-gem_bytes/file/CHANGELOG.md)
8
8
  [![Build
9
9
  Status](https://github.com/main-branch/bundler-gem_bytes/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/main-branch/bundler-gem_bytes/actions/workflows/continuous-integration.yml)
10
- [![Maintainability](https://api.codeclimate.com/v1/badges/2468fc247e5d66fc179f/maintainability)](https://codeclimate.com/github/main-branch/bundler-gem_bytes/maintainability)
11
- [![Test
12
- Coverage](https://api.codeclimate.com/v1/badges/2468fc247e5d66fc179f/test_coverage)](https://codeclimate.com/github/main-branch/bundler-gem_bytes/test_coverage)
13
10
  [![Conventional
14
11
  Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)
15
12
  [![Slack](https://img.shields.io/badge/slack-main--branch/bundler--gem_bytes-yellow.svg?logo=slack)](https://main-branch.slack.com/archives/C07RKRKTLDT)
@@ -36,18 +33,21 @@ own script**
36
33
 
37
34
  * [Installation](#installation)
38
35
  * [Usage](#usage)
39
- * [Example](#example)
40
- * [Handling Errors](#handling-errors)
36
+ * [Example](#example)
37
+ * [Handling Errors](#handling-errors)
41
38
  * [Development](#development)
39
+ * [How this gem works](#how-this-gem-works)
40
+ * [Debugging](#debugging)
41
+ * [Releasing](#releasing)
42
42
  * [Contributing](#contributing)
43
- * [Commit message guidelines](#commit-message-guidelines)
44
- * [Pull request guidelines](#pull-request-guidelines)
43
+ * [Commit message guidelines](#commit-message-guidelines)
44
+ * [Pull request guidelines](#pull-request-guidelines)
45
45
  * [License](#license)
46
46
  * [Code of Conduct](#code-of-conduct)
47
47
 
48
48
  ## Installation
49
49
 
50
- Install this bundler plugin as follows:
50
+ Install the `bundler gem-bytes` command as follows:
51
51
 
52
52
  ```shell
53
53
  bundle plugin install bunder-gem_bytes
@@ -79,42 +79,106 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
79
79
  workflow. You can also run `bin/console` for an interactive prompt that will allow
80
80
  you to experiment.
81
81
 
82
- To install this gem onto your local machine, run `bundle exec rake install`. To
83
- release a new version, update the version number in `version.rb`, and then run
84
- `bundle exec rake release`, which will create a git tag for the version, push git
85
- commits and the created tag, and push the `.gem` file to
86
- [rubygems.org](https://rubygems.org).
82
+ ### How this gem works
87
83
 
88
- To install this bundler plugin from the source code, run the following command from
89
- the project's root directory:
84
+ 1. The user runs the `bundler gem-bytes` command from the command line, passing the
85
+ path or URL to a GemBytes script:
90
86
 
91
- ```shell
92
- bundler plugin install --path . bundler-gem_bytes
93
- ```
87
+ ```shell
88
+ bundler gem-bytes [SCRIPT]
89
+ ```
94
90
 
95
- and then run `bundler plugin list` to make sure it was installed correctly:
91
+ 2. The `plugins.rb` file (in the root directory of this project) defines
92
+ `Bundler::GemBytes::BundlerCommand` class as the handler for the `gem-bytes`
93
+ bundler command:
96
94
 
97
- ```shell
98
- $ bundler plugin list
99
- bundler-gem_bytes
100
- -----
101
- gem-bytes
95
+ ```ruby
96
+ require 'bundler/gem_bytes'
102
97
 
103
- $
104
- ```
98
+ # Register Bundler::GemBytes::BundlerCommand as the handler for the `gem-bytes`
99
+ # bundler command
105
100
 
106
- Once installed, the bundler plugin can be run with the following command:
101
+ Bundler::Plugin::API.command('gem-bytes', Bundler::GemBytes::BundlerCommand)
102
+ ```
107
103
 
108
- ```shell
109
- bundler gem-bytes
110
- ```
104
+ 3. Bundler invokes the gem-bytes plugin by creating an instance of
105
+ `Bundler::GemBytes::BundlerCommand` and then calling `#exec(command, args)` on
106
+ that instance. Where:
107
+
108
+ * `command` is the bundler command given on the command line. It will always be
109
+ "gem-bytes".
110
+ * `args` is the array of any other arguments given on the command line after the
111
+ command. In this case, we expect the script path or URI.
112
+
113
+ 4. The `BundlerCommand` instance creates a `Bundler::GemBytes::ScriptExecutor`
114
+ instance and calls `#execute(path_or_uri)` on that instance. This method in turn
115
+ calls `Thor::Actions#apply(path_or_uri)` to load the external script and execute
116
+ it in the context of the `ScriptExecutor` instance.
111
117
 
112
- To uninstall the plugin, run:
118
+ The `#apply` method, part of the `Thor::Actions` module, loads and executes the
119
+ script within the context of the `ScriptExecutor` instance.
120
+
121
+ If an error occurs during script execution, `BundlerCommand` catches the error, outputs an error message to `stderr`, and exits with a status code of `1`.
122
+
123
+ 5. The `ScriptExecutor` class provides the environment/binding in which the GemBytes
124
+ script is executed, allowing the script to use instance methods and context from
125
+ `ScriptExecutor`. In addition to core Ruby and Active Support, the API available
126
+ to this script includes methods from both the
127
+ [`Thor::Actions`](https://github.com/rails/thor/wiki/Actions) and
128
+ `Bundler::GemBytes::Actions` modules, which provide utilities for file
129
+ manipulation, template generation, and other tasks essential for script execution.
130
+
131
+ ### Debugging
132
+
133
+ To debug this gem it is recommended that you create a test project and install
134
+ this plugin with bundler from source code as follows:
113
135
 
114
136
  ```shell
115
- bundler uninstall bundler-gem_bytes
137
+ # 1. Create a temp directory for testing (from the root directory of the project)
138
+ mkdir temp
139
+ cd temp
140
+
141
+ # 2. Create an new, empty RubyGem project to test
142
+ BUNDLE_IGNORE_CONFIG=TRUE bundle gem foo --no-test --no-ci --no-mit --no-coc --no-linter --no-changelog
143
+ cd foo
144
+
145
+ # 3. Install the plugin from source
146
+ BUNDLE_IGNORE_CONFIG=TRUE bundle plugin install --path ../.. bundler-gem_bytes
147
+
148
+ # 4. Create a gembytes script to add a development dependency on rubocop
149
+ cat <<SCRIPT > gem_bytes_script.rb
150
+ gemspec do
151
+ add_development_dependency "rubocop", "~> 1.68"
152
+ end
153
+ SCRIPT
154
+
155
+ # 5. Modify code, set breakpoints, or add binding.{irb|pry} calls to the source
156
+
157
+ # 6. Run the plugin
158
+ BUNDLE_IGNORE_CONFIG=TRUE bundle gem-bytes gem_bytes_script.rb
159
+
160
+ # Repeat 4 - 6 until satisified :)
116
161
  ```
117
162
 
163
+ ### Releasing
164
+
165
+ To release a new version of this gem, run `create-github-release [TYPE]` where
166
+ TYPE is MAJOR, MINOR, or PATCH according to SemVer based on the changes that
167
+ have been made since the last release:
168
+
169
+ * MAJOR: changes that break compatibility with previous versions, such as removing a
170
+ public method, changing a method signature, or modifying the expected behavior of a
171
+ method.
172
+ * MINOR: changes that add new features, enhance existing features, or deprecate
173
+ features in a backward-compatible way, such as adding a new method or improving
174
+ performance without breaking existing functionality.
175
+ * PATCH: changes that fix bugs or make other small modifications that do not affect
176
+ the API or alter existing functionality, such as fixing user-facing typos or
177
+ updating user documentation.
178
+
179
+ This command must be run from the project root directory with a clean worktree on the
180
+ default branch.
181
+
118
182
  ## Contributing
119
183
 
120
184
  Bug reports and pull requests are welcome on GitHub at
@@ -158,3 +222,36 @@ License](https://opensource.org/licenses/MIT).
158
222
  Everyone interacting in the Bundler::GemBytes project's codebases, issue trackers,
159
223
  chat rooms and mailing lists is expected to follow the [code of
160
224
  conduct](https://github.com/main-branch/bundler-gem_bytes/blob/main/CODE_OF_CONDUCT.md).
225
+
226
+ gemspec path do |spec_var, spec|
227
+ add_dependency 'example', '~> 1.1'
228
+ add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
229
+ add_development_dependency "rubocop", "~> 1.68"
230
+
231
+ remove_dependency "example"
232
+
233
+ attr "description", "#{spec.description}. Enhanced by GemBytes."
234
+ attr "author", ENV['USER']
235
+ attr "files", "Dir['lib/**/*.rb'] + Dir['bin/*']", quote: false
236
+ attr "authors", <% spec.authors %>.append('GemBytes').inspect, quote: false
237
+
238
+ remove_attr "license"
239
+
240
+ metadata "homepage_url", "https://github.com/example/"
241
+
242
+ remove_metadata "wiki_uri"
243
+
244
+ in_block("if RUBY_PLATFORM != 'java'", "end") do
245
+ development_dependency 'redcarpet', '~> 3.5'
246
+ development_dependency 'yard', '~> 0.9'
247
+ development_dependency 'yardstick', '~> 0.9'
248
+ end
249
+
250
+ code <<~CODE
251
+ if RUBY_PLATFORM != 'java'
252
+ <%= spec_var %>.add_development_dependency 'redcarpet', '~> 3.5'
253
+ <%= spec_var %>.add_development_dependency 'yard', '~> 0.9'
254
+ <%= spec_var %>.add_development_dependency 'yardstick', '~> 0.9'
255
+ end
256
+ CODE
257
+ end
data/Rakefile CHANGED
@@ -25,6 +25,13 @@ rescue Bundler::BundlerError => e
25
25
  exit e.status_code
26
26
  end
27
27
 
28
+ # Make it so that calling `rake release` just calls `rake release:rubygems_push` to
29
+ # avoid creating and pushing a new tag.
30
+
31
+ Rake::Task['release'].clear
32
+ desc 'Customized release task to avoid creating a new tag'
33
+ task release: 'release:rubygem_push'
34
+
28
35
  CLEAN << 'pkg'
29
36
  CLOBBER << 'Gemfile.lock'
30
37
 
@@ -56,6 +63,7 @@ unless RUBY_PLATFORM == 'java'
56
63
 
57
64
  YARD::Rake::YardocTask.new(:build) do |t|
58
65
  t.files = %w[lib/**/*.rb examples/**/*]
66
+ t.options = ['--markup-provider', 'redcarpet', '--markup', 'markdown']
59
67
  t.stats_options = ['--list-undoc']
60
68
  end
61
69
 
@@ -85,3 +93,4 @@ end
85
93
 
86
94
  CLOBBER << 'package-lock.json'
87
95
  CLOBBER << 'node_modules'
96
+ CLOBBER << '.bundle'
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parser/current'
4
+ require 'rubocop-ast'
5
+ require 'active_support/core_ext/object'
6
+
7
+ module Bundler
8
+ module GemBytes
9
+ module Actions
10
+ class Gemspec < Parser::TreeRewriter
11
+ # Holds the components of a attribute: a name and a value
12
+ #
13
+ # @api public
14
+ #
15
+ # Attributes in the gemspec look like the following:
16
+ #
17
+ # ```ruby
18
+ # Gem::Specification.new do |spec|
19
+ # spec.name = 'test'
20
+ # end
21
+ # ```
22
+ #
23
+ # @!attribute [r] name
24
+ # The name of the attribute
25
+ # @example
26
+ # attribute.name #=> "test"
27
+ #
28
+ # @return [String]
29
+ # @api public
30
+ #
31
+ # @!attribute [r] value
32
+ # The value of the attribute expressed as an AST tree
33
+ # @example
34
+ # attribute.value.to_sexp #=> 's(:str, "my_description")'
35
+ # @return [Parser::AST::Node]
36
+ # @api public
37
+ #
38
+ # @!method to_a()
39
+ # Converts the attribute into an array
40
+ # @example
41
+ # dependency.to_a #=> ["description", [:str, "my_description"]]
42
+ # @return [Array]
43
+ # @api public
44
+ #
45
+ Attribute = Struct.new(:name, :value) do
46
+ def to_a = [name, value.to_sexp_array]
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parser/current'
4
+ require 'rubocop-ast'
5
+ require 'active_support/core_ext/object'
6
+
7
+ module Bundler
8
+ module GemBytes
9
+ module Actions
10
+ class Gemspec < Parser::TreeRewriter
11
+ # Maps a dependency declaration to the AST that represents it
12
+ # @api public
13
+ #
14
+ # @!attribute [r] node
15
+ # The AST node for the attribute
16
+ # @example
17
+ # attribute_node.node #=> ...
18
+ # @return [Parser::AST::Node]
19
+ # @api public
20
+ #
21
+ # @!attribute [r] attribute
22
+ # The components of the attribute from the AST node
23
+ # @example
24
+ # attribute_node.attribute.to_a #=> ["description", [:str, "My deescription"]]
25
+ # @return [Dependency]
26
+ # @api public
27
+ #
28
+ AttributeNode = Struct.new(:node, :attribute)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parser/current'
4
+ require 'rubocop-ast'
5
+ require 'active_support/core_ext/object'
6
+
7
+ module Bundler
8
+ module GemBytes
9
+ module Actions
10
+ class Gemspec < Parser::TreeRewriter
11
+ # Remove a dependency in a gemspec
12
+ #
13
+ # If a dependency on the given gem is not found, this action does nothing.
14
+ #
15
+ # If one or more dependencies are found on the same gem as gem_name,
16
+ # the are removed from the gemspec.
17
+ #
18
+ # The gemspec is updated via calls to the tree_rewriter object.
19
+ #
20
+ # @!attribute [r] tree_rewriter
21
+ # The object that updates the source
22
+ # @return [Parser::TreeRewriter]
23
+ # @api private
24
+ #
25
+ # @!attribute [r] gemspec_block
26
+ # The root AST node of the Gem::Specification block from the gemspec
27
+ # @return [Parser::AST::Node]
28
+ # @api private
29
+ #
30
+ # @!attribute [r] receiver_name
31
+ # The name of the receiver for the Gem::Specification block
32
+ # @return [Symbol]
33
+ # @api private
34
+ #
35
+ # @!attribute [r] dependencies
36
+ # The dependency declarations found in the gemspec file
37
+ # @return [Array<DependencyNode>]
38
+ # @api private
39
+ #
40
+ # @!attribute [r] gem_name
41
+ # The name of the gem to remove dependency on
42
+ # @return [String]
43
+ # @api private
44
+ #
45
+ # @api public
46
+ class DeleteDependency
47
+ # Initializes the delete dependency action
48
+ # @param tree_rewriter [Parser::TreeRewriter] The object that updates the source
49
+ # @param gemspec_block [Parser::AST::Node] The Gem::Specification block
50
+ # @param receiver_name [Symbol] The name of the receiver for the Gem::Specification block
51
+ # @param dependencies [Array<DependencyNode>] The dependency declarations found in the gemspec file
52
+ # @api private
53
+ def initialize(tree_rewriter, gemspec_block, receiver_name, dependencies)
54
+ @tree_rewriter = tree_rewriter
55
+ @gemspec_block = gemspec_block
56
+ @receiver_name = receiver_name
57
+ @dependencies = dependencies
58
+ end
59
+
60
+ attr_reader :tree_rewriter, :gemspec_block, :receiver_name, :dependencies, :gem_name
61
+
62
+ # Adds or updates a dependency to the Gem::Specification block
63
+ #
64
+ # @example
65
+ # delete_dependency = DeleteDependency.new(tree_rewriter, gemspec_block, receiver_name, dependencies)
66
+ # gem_name = 'rubocop'
67
+ # depete_dependency.call(gem_name)
68
+ # @param gem_name [String] The name of the gem to remove dependency on
69
+ # @return [void]
70
+ # @api public
71
+ def call(gem_name)
72
+ @gem_name = gem_name
73
+ matching_dependencies = dependencies.select { |d| d.dependency.gem_name == gem_name }
74
+
75
+ delete_dependencies(matching_dependencies) if matching_dependencies.any?
76
+ end
77
+
78
+ # Removes the matching dependencies from the gemspec
79
+ # @param matching_dependencies [Array<DependencyNode>] The existing dependencies that match gem_name
80
+ # @return [void]
81
+ # @api private
82
+ def delete_dependencies(matching_dependencies)
83
+ matching_dependencies.each do |found_dependency|
84
+ tree_rewriter.replace(full_line_range(found_dependency), '')
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ # Expand the range for a node to include any leading whitespace and newline
91
+ # @param dependency_node [DependencyNode] The node to remove
92
+ # @return [Parser::Source::Range] The range of the whole line including whitespace
93
+ # @api private
94
+ def full_line_range(dependency_node)
95
+ range = dependency_node.node.loc.expression
96
+ source_buffer = range.source_buffer
97
+ # The whole line including leading and trailing whitespace
98
+ line_range = source_buffer.line_range(range.line)
99
+ # Expand the range to include the leading newline
100
+ line_range.with(begin_pos: line_range.begin_pos - 1)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parser/current'
4
+ require 'rubocop-ast'
5
+ require 'active_support/core_ext/object'
6
+
7
+ module Bundler
8
+ module GemBytes
9
+ module Actions
10
+ class Gemspec < Parser::TreeRewriter
11
+ # Holds the components of a dependency declaration
12
+ #
13
+ # @api public
14
+ #
15
+ # A dependency declaration is a call to `add_dependency`,
16
+ # `add_runtime_dependency`, or `add_development_dependency` in the
17
+ # Gem::Specification block.
18
+ #
19
+ # For example, the following is a dependency declaration:
20
+ #
21
+ # ```ruby
22
+ # spec.add_dependency 'rubocop', '~> 1.0'
23
+ # ```
24
+ #
25
+ # Would be represented by a Dependency object with the following
26
+ # attributes:
27
+ # * method_name: :add_dependency
28
+ # * gem_name: 'rubocop'
29
+ # * version_constraint: '~> 1.0'
30
+ #
31
+ # @!attribute [r] method_name
32
+ # The name of the method called to add the dependency
33
+ #
34
+ # Must be one of the following:
35
+ #
36
+ # * :add_dependency
37
+ # * :add_runtime_dependency
38
+ # * :add_development_dependency
39
+ #
40
+ # @example
41
+ # dependency.method_name #=> :add_dependency
42
+ #
43
+ # @return [Symbol]
44
+ # @api public
45
+ #
46
+ # @!attribute [r] gem_name
47
+ # The name of the gem being depended on
48
+ # @example
49
+ # dependency.gem_name #=> "rubocop"
50
+ # @return [String]
51
+ # @api public
52
+ #
53
+ # @!attribute [r] version_constraints
54
+ # The version constraints for the dependency
55
+ # @example
56
+ # dependency.version_constraints #=> ["~> 1.68", ">= 1.68.3"]
57
+ # @return [Array<String>]
58
+ # @api public
59
+ #
60
+ # @!method to_a()
61
+ # Converts the dependency into an array
62
+ # @example
63
+ # dependency.to_a #=> [:add_runtime_dependency, "rubocop", "~> 1.68"]
64
+ # @return [Array]
65
+ # @api public
66
+ #
67
+ Dependency = Struct.new(:method_name, :gem_name, :version_constraints) do
68
+ def to_a = [method_name, gem_name, *version_constraints]
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parser/current'
4
+ require 'rubocop-ast'
5
+ require 'active_support/core_ext/object'
6
+
7
+ module Bundler
8
+ module GemBytes
9
+ module Actions
10
+ class Gemspec < Parser::TreeRewriter
11
+ # Maps a dependency declaration to the AST that represents it
12
+ # @api public
13
+ #
14
+ # @!attribute [r] node
15
+ # The AST node for the dependency declaration
16
+ # @example
17
+ # dependency_node.node #=> ...
18
+ # @return [Parser::AST::Node]
19
+ # @api public
20
+ #
21
+ # @!attribute [r] dependency
22
+ # The components of the dependency declaration from the AST node
23
+ # @example
24
+ # dependency_node.dependency.to_a #=> [:add_dependency, 'rubocop', '~> 1.68']
25
+ # @return [Dependency]
26
+ # @api public
27
+ #
28
+ DependencyNode = Struct.new(:node, :dependency)
29
+ end
30
+ end
31
+ end
32
+ end