himg 0.0.1 → 0.0.3

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: 516bc67aa868ad60941f30c3da0ae3394c52527d98066260ec6eccbf7c37d71c
4
- data.tar.gz: e2b6109e2d740755aca950d0615de4e45cb2d3d988c323d32425b3bd835f8378
3
+ metadata.gz: 286080c98560f491c524867c0986edd71e7e14bc912a50a2a72d627d4cb22e34
4
+ data.tar.gz: 435a08c13f0211d694ca477d4ce8a7afba24c686d088a7b7831c0397177d127c
5
5
  SHA512:
6
- metadata.gz: 3eedcbb8954b86e31808c6a4cfb13b76db86086c7c243babd9ecf244cc0d0bb8d6b0dab174b06f6d79420d1eb75ee58e6e3c1f9ca0694b08ded2c8a5a2283c92
7
- data.tar.gz: f7f2c9c1b9e9731a9c7baff46b5307508e37c9204a232b55b29f9f1dda69cd2ae66ddcc51d91936689c716a0be1f89396388cbcffaf2914d3b264e02a78f19eb
6
+ metadata.gz: d5ca027f7d92741dc71b872a5308a05228c9e7c7743ebcfd976175f3c4a5a0482d3831e0d3f664aa1a7870353e8d2d482c1e545b0fa558d802ca3131282323bd
7
+ data.tar.gz: e4a9e936a5d96a1574c9af213912bed55de8e25af94775007397a70a7bdebc9f5b41519fc35668738c0929e9f50821b18f1c58d0897f84443334fcba15b4973c
data/.rubocop.yml ADDED
@@ -0,0 +1,20 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
3
+
4
+ Style/StringLiterals:
5
+ EnforcedStyle: double_quotes
6
+
7
+ Style/StringLiteralsInInterpolation:
8
+ EnforcedStyle: double_quotes
9
+
10
+ Style/FrozenStringLiteralComment:
11
+ Enabled: false
12
+
13
+ Metrics/BlockLength:
14
+ Enabled: false
15
+
16
+ Bundler/OrderedGems:
17
+ Enabled: false
18
+
19
+ Layout/ExtraSpacing:
20
+ Enabled: false
data/Appraisals ADDED
@@ -0,0 +1,40 @@
1
+ appraise "plain-ruby" do
2
+ remove_gem "rails"
3
+ remove_gem "puma"
4
+ end
5
+
6
+ appraise "rails-6" do
7
+ remove_gem "puma"
8
+ gem "rails", "~> 6.0"
9
+ gem "rspec-rails", "~> 6.0"
10
+ gem "concurrent-ruby", "1.3.4" # Logger dependency fix, see: https://stackoverflow.com/questions/79360526/uninitialized-constant-activesupportloggerthreadsafelevellogger-nameerror
11
+ gem "bigdecimal", "~> 1.4" # See: https://github.com/rails/rails/issues/34822
12
+ gem "drb"
13
+ end
14
+
15
+ appraise "rails-7-0" do
16
+ remove_gem "puma"
17
+ gem "rails", "~> 7.0.0"
18
+ gem "rspec-rails", "~> 7.0"
19
+ gem "concurrent-ruby", "1.3.4" # Logger dependency fix, see: https://stackoverflow.com/questions/79360526/uninitialized-constant-activesupportloggerthreadsafelevellogger-nameerror
20
+ gem "bigdecimal", "~> 1.4" # See: https://github.com/rails/rails/issues/34822
21
+ gem "drb"
22
+ end
23
+
24
+ appraise "rails-7-1" do
25
+ remove_gem "puma"
26
+ gem "rails", "~> 7.1.0"
27
+ gem "rspec-rails", "~> 7.0"
28
+ end
29
+
30
+ appraise "rails-7-2" do
31
+ remove_gem "puma"
32
+ gem "rails", "~> 7.2.0"
33
+ gem "rspec-rails", "~> 7.0"
34
+ end
35
+
36
+ appraise "rails-8" do
37
+ remove_gem "puma"
38
+ gem "rails", "~> 8.0"
39
+ gem "rspec-rails", "~> 7.0"
40
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.3] - 2025-04-22
4
+
5
+ - Ensure that when render height is expanded to fit the content that we update
6
+ the height we try to write in the png metadata to match.
7
+ - Rust creates a ruby string with the binary png data so we don't need to convert with .pack("C*")
8
+ - Himg::Error wraps errors from a Rust Result<_,Err>
9
+ - Added OpenGraph metadata example
10
+ - Default dimensions of 720x405 to match the ideal 16:9 ratio and image size
11
+ for sharing og-image on messengers and social media.
12
+
13
+ ## [0.0.2] - 2025-04-21
14
+
15
+ - Adds Rails support via a ActionView template handler.
16
+ Takes views like `action.show.erb`, pre-processes them with Erb and renders
17
+ to a .png with 'image/png' set as the MIME type.
18
+ - Adds a `ActionController::Renderer` so `render himg: '<div>Some HTML</div>'`
19
+ can be used either directly or from a `format.png`/`format.himg` block.
20
+
3
21
  ## [0.0.1] - 2025-04-19
4
22
 
5
23
  - Initial alpha
data/Cargo.lock CHANGED
@@ -1065,7 +1065,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
1065
1065
 
1066
1066
  [[package]]
1067
1067
  name = "himg"
1068
- version = "0.0.1"
1068
+ version = "0.0.3"
1069
1069
  dependencies = [
1070
1070
  "blitz-dom",
1071
1071
  "blitz-html",
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Himg
1
+ # Himg: The Hyper Image Generator
2
2
 
3
- Library for generating an image from HTML
3
+ You give it HTML and it gives back an image!
4
4
 
5
5
  Parses a minimal subset of HTML/CSS, fetches nested resources, renders an image on the GPU.
6
6
 
@@ -8,31 +8,81 @@ Uses rust libraries to do this in a fast, hopefully safe way.
8
8
 
9
9
  In Rails this will mean you can process user.himg.erb to display an image including data from a user's profile.
10
10
 
11
- ## Installation
11
+ ## CAVEATS
12
+
13
+ 1. This is **pre-alpha** software, don't expect it to work yet.
14
+ 2. Rendering requires a GPU. Awaiting CPU support in vello, which Canva may be working on.
15
+ 3. Performance needs tuning. Both in the underlying blitz library and how data is passed between Rust and Ruby
16
+ 4. Network requests can be made: don't use this library with untrusted inputs.
17
+ 5. file:// URLs are resolved: this could expose files on your computer.
18
+ 6. Native extensions are not yet being published for different os/arch
19
+ 7. Verbose logging is hardcoded
12
20
 
13
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
21
+ ## Installation
14
22
 
15
23
  Install the gem and add to the application's Gemfile by executing:
16
24
 
17
25
  ```bash
18
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
26
+ bundle add himg
19
27
  ```
20
28
 
21
29
  If bundler is not being used to manage dependencies, install the gem by executing:
22
30
 
23
31
  ```bash
24
- gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
32
+ gem install himg
25
33
  ```
26
34
 
27
35
  ## Usage
28
36
 
29
- ### Run from Ruby
37
+ ### Ruby
30
38
 
31
39
  ```ruby
32
40
  png = Himg.render("<html bgcolor='blue'></html>")
33
41
  ```
34
42
 
43
+ ### Rails
44
+
45
+ Simply add a `show.himg.erb`!
46
+
47
+ ```erb
48
+ <div><%= @username %></div>
49
+ ```
50
+
51
+ ### Adding OpenGraph Meta Tags
52
+
53
+ Once you've added a view template for your resource, you can use it to generate image cards that will be shown when the page is shared on messenger apps or social media.
54
+
55
+ ```html
56
+ <meta property="og:title" content="<%= @user.username %>" />
57
+ <meta property="og:description" content="<%= @user.tagline %>" />
58
+ <meta property="og:image" content="<%= user_url(@user.username, format: :png) %>" />
59
+ ```
60
+
61
+ ### Advanced Rails Usage
62
+
63
+ A :himg template handler is registered and will be called by rails' `default_render` method automatically when the corresponding view is found. This can be `show.himg` for a static image, or `show.himg.erb` to use variables from the controller.
64
+
65
+ If you prefer you could also use `render himg: "<div>My Data</div>"` instead, but should be careful with untrusted input if constructing HTML manually.
66
+
67
+ To be explicit in the controler you can also use `respond_to` style:
68
+
69
+ ```ruby
70
+ respond_to do |format|
71
+ format.html
72
+ format.himg
73
+ end
74
+ ```
75
+
76
+ ```ruby
77
+ respond_to do |format|
78
+ format.html
79
+ format.himg { render himg: '<h1 style="text-align: center;">Recent Users</h1>' }
80
+ format.png { render himg: '<div>For .png URLs</div>' }
81
+ end
82
+ ```
83
+
35
84
  ### Run directly from the command line to output an image
85
+
36
86
  ```bash
37
87
  bundle exec cargo run --example file
38
88
  bundle exec cargo run --example file -- path/to/file.html
@@ -40,9 +90,21 @@ bundle exec cargo run --example file -- path/to/file.html
40
90
 
41
91
  ## Development
42
92
 
43
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
44
-
45
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
93
+ 1. Run `bin/setup` to install dependencies.
94
+ 2. Run `rake spec` to run the tests with the default development setup
95
+ 3. Run `appraisal rake spec` to run tests against different versions of rails and to confirm that the gem works in a plain ruby environment
96
+ 4. Run `bin/console` for an interactive prompt that will allow you to experiment.
97
+ 5. Run `RAILS_ENV=development bundle exec spec/dummy/dummy_rails server` to check the dummy app.
98
+ - http://localhost:3000/users/jamedjo.png will display an opengraph compatible png
99
+ - http://localhost:3000/users/jamedjo.himg will also render the same png
100
+ - http://localhost:3000/users/jamedjo will render an HTML page with opengraph meta tags
101
+ 6. To install this gem onto your local machine, run `bundle exec rake install`.
102
+
103
+ ## Releases
104
+
105
+ To release a new version:
106
+ 1. Run `rake bump:patch` to update the version numbers in `version.rb` and `ext/himg/Cargo.toml`.
107
+ 3. Run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
46
108
 
47
109
  ## Contributing
48
110
 
data/Rakefile CHANGED
@@ -5,7 +5,9 @@ require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- require "standard/rake"
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
9
11
 
10
12
  require "rb_sys/extensiontask"
11
13
 
@@ -17,4 +19,8 @@ RbSys::ExtensionTask.new("himg", GEMSPEC) do |ext|
17
19
  ext.lib_dir = "lib/himg"
18
20
  end
19
21
 
20
- task default: %i[compile spec standard]
22
+ require "bump/tasks"
23
+ Bump.replace_in_default = %w[ext/himg/Cargo.toml]
24
+ Bump.changelog = :editor
25
+
26
+ task default: %i[compile rubocop]
data/Steepfile CHANGED
@@ -17,13 +17,3 @@ target :lib do
17
17
  # hash[D::Ruby::NoMethod] = :information
18
18
  # end
19
19
  end
20
-
21
- #target :test do
22
- # unreferenced! # Skip type checking the `lib` code when types in `test` target is changed
23
- # signature "sig/test" # Put RBS files for tests under `sig/test`
24
- # check "test" # Type check Ruby scripts under `test`
25
-
26
- # configure_code_diagnostics(D::Ruby.lenient) # Weak type checking for test code
27
-
28
- # # library "pathname" # Standard libraries
29
- #end
data/ext/himg/Cargo.toml CHANGED
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  name = "himg"
3
3
  description = "ruby bindings to expose a blitz html->png pipeline"
4
- version = "0.0.1"
4
+ version = "0.0.3"
5
5
  edition = "2024"
6
6
  authors = ["James Edwards-Jones <git@jamedjo.co.uk>"]
7
7
  license = "MIT"
@@ -43,7 +43,7 @@ async fn main() {
43
43
  let mut file = File::create(&out_path).unwrap();
44
44
 
45
45
  // Encode buffer as PNG and write it to a file
46
- write_png(&mut file, &buffer, options.image_size.scaled_width(), options.image_size.scaled_height());
46
+ write_png(&mut file, &buffer, options.image_size.scaled_width(), options.image_size.scaled_height()).unwrap();
47
47
  logger.log("Wrote out png");
48
48
 
49
49
  logger.log_total_time("\nDone");
@@ -11,12 +11,17 @@ use crate::image_size::ImageSize;
11
11
  use crate::logger::Logger;
12
12
  use crate::options::Options;
13
13
 
14
+ pub struct RenderOutput {
15
+ pub buffer: Vec<u8>,
16
+ pub image_size: ImageSize,
17
+ }
18
+
14
19
  pub async fn html_to_image(
15
20
  html: &str,
16
21
  base_url: Option<String>,
17
22
  options: Options,
18
23
  logger: &mut dyn Logger,
19
- ) -> Vec<u8> {
24
+ ) -> RenderOutput {
20
25
  let (mut recv, callback) = MpscCallback::new();
21
26
  logger.log("Initial config");
22
27
 
@@ -83,5 +88,8 @@ pub async fn html_to_image(
83
88
 
84
89
  logger.log("Rendered to buffer");
85
90
 
86
- buffer
91
+ RenderOutput {
92
+ buffer: buffer,
93
+ image_size: render_size,
94
+ }
87
95
  }
data/ext/himg/src/lib.rs CHANGED
@@ -11,22 +11,23 @@ pub use writer::write_png;
11
11
  pub use logger::{Logger, TimedLogger};
12
12
 
13
13
  use blitz_traits::{ColorScheme};
14
- use magnus::{function, prelude::*, Error, Ruby};
14
+ use magnus::{function, prelude::*, ExceptionClass, Error, Ruby};
15
15
 
16
- pub fn render_blocking(html: String) -> Vec<u8> {
17
- tokio::runtime::Runtime::new()
18
- .unwrap()
19
- .block_on(render(html))
16
+ pub fn render_blocking(html: String) -> Result<Vec<u8>, std::io::Error> {
17
+ let runtime = tokio::runtime::Runtime::new()?;
18
+
19
+ runtime.block_on(render(html))
20
20
  }
21
21
 
22
- pub async fn render(html: String) -> Vec<u8> {
22
+ // render_to_bytes, render_to_string, render_to_file, render_to_io
23
+ pub async fn render(html: String) -> Result<Vec<u8>, std::io::Error> {
23
24
  let mut logger = TimedLogger::init();
24
25
 
25
26
  // Configure viewport dimensions
26
27
  let options = Options {
27
28
  image_size: ImageSize {
28
- width: 1200, //TODO: pass this in
29
- height: 800, //TODO: decide if this will be fixed or dynamic from the document
29
+ width: 720, //TODO: pass this in
30
+ height: 405, //TODO: decide if this will be fixed or dynamic from the document
30
31
  hidpi_scale: 1.0,
31
32
  },
32
33
  color_scheme: ColorScheme::Light,
@@ -36,15 +37,24 @@ pub async fn render(html: String) -> Vec<u8> {
36
37
  // Render to Image
37
38
  //let base_url = format!("file://{}", path_string.clone());
38
39
  let base_url = None;
39
- let image_data = html_to_image(&html, base_url, options, &mut logger).await;
40
+ let render_output = html_to_image(&html, base_url, options, &mut logger).await;
40
41
 
41
42
  // Determine output path, and open a file at that path.
42
43
  let mut output_buffer: Vec<u8> = Vec::new();
43
44
 
44
45
  // Encode buffer as PNG and write it to a file
45
- write_png(&mut output_buffer, &image_data, options.image_size.scaled_width(), options.image_size.scaled_height());
46
+ write_png(&mut output_buffer, &render_output.buffer, render_output.image_size.scaled_width(), render_output.image_size.scaled_height())?;
47
+
48
+ Ok(output_buffer)
49
+ }
46
50
 
47
- output_buffer
51
+ pub fn render_blocking_rb(ruby: &Ruby, html: String) -> Result<magnus::RString, magnus::Error> {
52
+ let exception_class = ExceptionClass::from_value(magnus::eval("Himg::Error").unwrap()).unwrap();
53
+
54
+ match render_blocking(html) {
55
+ Ok(data) => Ok(ruby.str_from_slice(&data)),
56
+ Err(e) => Err(Error::new(exception_class, format!("{}", e))),
57
+ }
48
58
  }
49
59
 
50
60
  #[magnus::init]
@@ -52,7 +62,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
52
62
  let module = ruby.define_module("Himg")?;
53
63
 
54
64
  //TODO: Allow optional base_url for resolving linked resources (stylesheets, images, fonts, etc)
55
- module.define_singleton_method("render", function!(render_blocking, 1))?;
65
+ module.define_singleton_method("render", function!(render_blocking_rb, 1))?;
66
+
56
67
  Ok(())
57
68
  }
58
69
 
@@ -4,9 +4,9 @@ use png::{Encoder, ColorType, BitDepth, PixelDimensions, Unit};
4
4
  const INCHES_PER_METER: f64 = 39.3701;
5
5
  const DEFAULT_DPI: f64 = 144.0;
6
6
 
7
- pub fn write_png<W: Write>(writer: W, buffer: &[u8], width: u32, height: u32) {
7
+ pub fn write_png<W: Write>(writer: W, buffer: &[u8], width: u32, height: u32) -> Result<(), std::io::Error> {
8
8
  let encoder = create_encoder(writer, width, height, DEFAULT_DPI);
9
- write_data(encoder, buffer);
9
+ write_data(encoder, buffer)
10
10
  }
11
11
 
12
12
  fn create_encoder<'a, W: Write>(writer: W, width: u32, height: u32, dpi: f64) -> Encoder<'a, W> {
@@ -24,10 +24,11 @@ fn create_encoder<'a, W: Write>(writer: W, width: u32, height: u32, dpi: f64) ->
24
24
  encoder
25
25
  }
26
26
 
27
- fn write_data<W: Write>(encoder: Encoder<W>, buffer: &[u8]) {
28
- //TODO: Better error handling instead of unwrap
29
- let mut writer = encoder.write_header().unwrap();
27
+ fn write_data<W: Write>(encoder: Encoder<W>, buffer: &[u8]) -> Result<(), std::io::Error> {
28
+ let mut writer = encoder.write_header()?;
30
29
 
31
- writer.write_image_data(buffer).unwrap();
32
- writer.finish().unwrap();
30
+ writer.write_image_data(buffer)?;
31
+ writer.finish()?;
32
+
33
+ Ok(())
33
34
  }
@@ -0,0 +1,5 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec path: "../"
@@ -0,0 +1,181 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ himg (0.0.2)
5
+ rb_sys (~> 0.9)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (8.0.2)
11
+ base64
12
+ benchmark (>= 0.3)
13
+ bigdecimal
14
+ concurrent-ruby (~> 1.0, >= 1.3.1)
15
+ connection_pool (>= 2.2.5)
16
+ drb
17
+ i18n (>= 1.6, < 2)
18
+ logger (>= 1.4.2)
19
+ minitest (>= 5.1)
20
+ securerandom (>= 0.3)
21
+ tzinfo (~> 2.0, >= 2.0.5)
22
+ uri (>= 0.13.1)
23
+ appraisal (2.5.0)
24
+ bundler
25
+ rake
26
+ thor (>= 0.14.0)
27
+ ast (2.4.3)
28
+ base64 (0.2.0)
29
+ benchmark (0.4.0)
30
+ bigdecimal (3.1.9)
31
+ bump (0.10.0)
32
+ concurrent-ruby (1.3.5)
33
+ connection_pool (2.5.1)
34
+ csv (3.3.4)
35
+ date (3.4.1)
36
+ debug (1.10.0)
37
+ irb (~> 1.10)
38
+ reline (>= 0.3.8)
39
+ diff-lcs (1.6.1)
40
+ drb (2.2.1)
41
+ ffi (1.17.2)
42
+ ffi (1.17.2-aarch64-linux-gnu)
43
+ ffi (1.17.2-aarch64-linux-musl)
44
+ ffi (1.17.2-arm-linux-gnu)
45
+ ffi (1.17.2-arm-linux-musl)
46
+ ffi (1.17.2-arm64-darwin)
47
+ ffi (1.17.2-x86-linux-gnu)
48
+ ffi (1.17.2-x86-linux-musl)
49
+ ffi (1.17.2-x86_64-darwin)
50
+ ffi (1.17.2-x86_64-linux-gnu)
51
+ ffi (1.17.2-x86_64-linux-musl)
52
+ fileutils (1.7.3)
53
+ i18n (1.14.7)
54
+ concurrent-ruby (~> 1.0)
55
+ io-console (0.8.0)
56
+ irb (1.15.2)
57
+ pp (>= 0.6.0)
58
+ rdoc (>= 4.0.0)
59
+ reline (>= 0.4.2)
60
+ json (2.10.2)
61
+ language_server-protocol (3.17.0.4)
62
+ lint_roller (1.1.0)
63
+ listen (3.9.0)
64
+ rb-fsevent (~> 0.10, >= 0.10.3)
65
+ rb-inotify (~> 0.9, >= 0.9.10)
66
+ logger (1.7.0)
67
+ minitest (5.25.5)
68
+ mutex_m (0.3.0)
69
+ parallel (1.27.0)
70
+ parser (3.3.8.0)
71
+ ast (~> 2.4.1)
72
+ racc
73
+ pp (0.6.2)
74
+ prettyprint
75
+ prettyprint (0.2.0)
76
+ prism (1.4.0)
77
+ psych (5.2.3)
78
+ date
79
+ stringio
80
+ racc (1.8.1)
81
+ rainbow (3.1.1)
82
+ rake (13.2.1)
83
+ rake-compiler (1.3.0)
84
+ rake
85
+ rake-compiler-dock (1.9.1)
86
+ rb-fsevent (0.11.2)
87
+ rb-inotify (0.11.1)
88
+ ffi (~> 1.0)
89
+ rb_sys (0.9.111)
90
+ rake-compiler-dock (= 1.9.1)
91
+ rbs (3.9.2)
92
+ logger
93
+ rdoc (6.13.1)
94
+ psych (>= 4.0.0)
95
+ regexp_parser (2.10.0)
96
+ reline (0.6.1)
97
+ io-console (~> 0.5)
98
+ rspec (3.13.0)
99
+ rspec-core (~> 3.13.0)
100
+ rspec-expectations (~> 3.13.0)
101
+ rspec-mocks (~> 3.13.0)
102
+ rspec-core (3.13.3)
103
+ rspec-support (~> 3.13.0)
104
+ rspec-expectations (3.13.3)
105
+ diff-lcs (>= 1.2.0, < 2.0)
106
+ rspec-support (~> 3.13.0)
107
+ rspec-mocks (3.13.2)
108
+ diff-lcs (>= 1.2.0, < 2.0)
109
+ rspec-support (~> 3.13.0)
110
+ rspec-support (3.13.2)
111
+ rubocop (1.75.2)
112
+ json (~> 2.3)
113
+ language_server-protocol (~> 3.17.0.2)
114
+ lint_roller (~> 1.1.0)
115
+ parallel (~> 1.10)
116
+ parser (>= 3.3.0.2)
117
+ rainbow (>= 2.2.2, < 4.0)
118
+ regexp_parser (>= 2.9.3, < 3.0)
119
+ rubocop-ast (>= 1.44.0, < 2.0)
120
+ ruby-progressbar (~> 1.7)
121
+ unicode-display_width (>= 2.4.0, < 4.0)
122
+ rubocop-ast (1.44.1)
123
+ parser (>= 3.3.7.2)
124
+ prism (~> 1.4)
125
+ ruby-progressbar (1.13.0)
126
+ securerandom (0.4.1)
127
+ steep (1.10.0)
128
+ activesupport (>= 5.1)
129
+ concurrent-ruby (>= 1.1.10)
130
+ csv (>= 3.0.9)
131
+ fileutils (>= 1.1.0)
132
+ json (>= 2.1.0)
133
+ language_server-protocol (>= 3.17.0.4, < 4.0)
134
+ listen (~> 3.0)
135
+ logger (>= 1.3.0)
136
+ mutex_m (>= 0.3.0)
137
+ parser (>= 3.1)
138
+ rainbow (>= 2.2.2, < 4.0)
139
+ rbs (~> 3.9)
140
+ securerandom (>= 0.1)
141
+ strscan (>= 1.0.0)
142
+ terminal-table (>= 2, < 5)
143
+ uri (>= 0.12.0)
144
+ stringio (3.1.7)
145
+ strscan (3.1.3)
146
+ terminal-table (4.0.0)
147
+ unicode-display_width (>= 1.1.1, < 4)
148
+ thor (1.3.2)
149
+ tzinfo (2.0.6)
150
+ concurrent-ruby (~> 1.0)
151
+ unicode-display_width (3.1.4)
152
+ unicode-emoji (~> 4.0, >= 4.0.4)
153
+ unicode-emoji (4.0.4)
154
+ uri (1.0.3)
155
+
156
+ PLATFORMS
157
+ aarch64-linux-gnu
158
+ aarch64-linux-musl
159
+ arm-linux-gnu
160
+ arm-linux-musl
161
+ arm64-darwin
162
+ x86-linux-gnu
163
+ x86-linux-musl
164
+ x86_64-darwin
165
+ x86_64-linux-gnu
166
+ x86_64-linux-musl
167
+
168
+ DEPENDENCIES
169
+ appraisal
170
+ bump
171
+ debug
172
+ himg!
173
+ irb
174
+ rake
175
+ rake-compiler
176
+ rspec
177
+ rubocop
178
+ steep
179
+
180
+ BUNDLED WITH
181
+ 2.6.7
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 6.0"
6
+ gem "rspec-rails", "~> 6.0"
7
+ gem "concurrent-ruby", "1.3.4"
8
+ gem "bigdecimal", "~> 1.4"
9
+ gem "drb"
10
+
11
+ gemspec path: "../"