nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: lovell/sharp
Pull request #4347 (2025-03-16 12:18:45)

Ensure Yarn PnP hash calculation works with pre-releases
Before:
```console
$ ls -1 .yarn/unplugged | grep sharp-libvips-linux-x64
@img-sharp-libvips-linux-x64-npm-1.1.0-rc4-5841416c64
$ yarn node -p "require('sharp/lib/libvips').yarnLocator()"
6e8b62218c
```

After:
```console
$ ls -1 .yarn/unplugged | grep sharp-libvips-linux-x64
@img-sharp-libvips-linux-x64-npm-1.1.0-rc4-5841416c64
$ yarn node -p "require('sharp/lib/libvips').yarnLocator()"
5841416c64
```

kleisauke: An alternative approach could be to simply remove the `semverCoerce()` call, as Yarn Plug'n'Play likely(?) uses the raw tag value here (e.g. `2.0` remains `2.0` rather than being converted to `2.0.0` first). However, this would cause issues when referencing these dependencies with version ranges (e.g. `^1.1.0`, `=1.1.0`, etc.).

Patch:
diff --git a/lib/libvips.js b/lib/libvips.js
index c9927e7a..9a563975 100644
--- a/lib/libvips.js
+++ b/lib/libvips.js
@@ -113,7 +113,9 @@ const sha512 = (s) => createHash('sha512').update(s).digest('hex');
 const yarnLocator = () => {
   try {
     const identHash = sha512(`imgsharp-libvips-${buildPlatformArch()}`);
-    const npmVersion = semverCoerce(optionalDependencies[`@img/sharp-libvips-${buildPlatformArch()}`]).version;
+    const npmVersion = semverCoerce(optionalDependencies[`@img/sharp-libvips-${buildPlatformArch()}`], {
+      includePrerelease: true
+    }).version;
     return sha512(`${identHash}npm:${npmVersion}`).slice(0, 10);
   } catch {}
   return '';


Test patch:
diff --git a/test/unit/libvips.js b/test/unit/libvips.js
index 5578ff42..18d33f19 100644
--- a/test/unit/libvips.js
+++ b/test/unit/libvips.js
@@ -179,7 +179,7 @@ describe('libvips binaries', function () {
       process.env.npm_config_arch = 's390x';
       process.env.npm_config_libc = '';
       const locatorHash = libvips.yarnLocator();
-      assert.strictEqual(locatorHash, '9b2ea457de');
+      assert.strictEqual(locatorHash, 'e34c58507a');
       delete process.env.npm_config_platform;
       delete process.env.npm_config_arch;
       delete process.env.npm_config_libc;
Repository: newrelic/elixir_agent
Pull request #517 (2025-03-05 06:35:06)

Add extended attributes for macro spans
This PR adds "extended attributes" for Spans generated with the `NewRelic.span` macro, as well as instrumentation that leverages `Tracer.Direct` internally.

binaryseed: Looks like a flake 🤷 

Patch:
diff --git a/lib/new_relic/tracer/direct.ex b/lib/new_relic/tracer/direct.ex
index 5041c7a..42d2f6e 100644
--- a/lib/new_relic/tracer/direct.ex
+++ b/lib/new_relic/tracer/direct.ex
@@ -84,6 +84,13 @@ defmodule NewRelic.Tracer.Direct do
           attributes: attributes
         )
 
+        if NewRelic.Config.feature?(:extended_attributes) do
+          NewRelic.incr_attributes(
+            "span.#{primary_name}.call_count": 1,
+            "span.#{primary_name}.duration_ms": duration
+          )
+        end
+
         NewRelic.report_metric({:function, primary_name}, duration_s: duration_s)
 
         NewRelic.DistributedTrace.reset_span(


Test patch:
diff --git a/test/span_event_test.exs b/test/span_event_test.exs
index d892e74..36e5b0c 100644
--- a/test/span_event_test.exs
+++ b/test/span_event_test.exs
@@ -196,6 +196,11 @@ defmodule SpanEventTest do
     single_span = TestHelper.find_event(span_events, "single.span")
 
     assert single_span[:category] == "generic"
+
+    events = TestHelper.gather_harvest(Collector.TransactionEvent.Harvester)
+    tx_event = TestHelper.find_event(events, "WebTransaction/Plug/GET/span_macro")
+
+    assert tx_event[:"span.another.span.call_count"] == 1
   end
 
   test "report span events via function tracer inside transaction inside a DT" do
Repository: newrelic/elixir_agent
Pull request #525 (2025-05-19 17:36:11)

Bump version 1.35.0
* Bump version 1.35.0
* Also fixes a stray flaky test


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5880997..23088ee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
 ## CHANGELOG
 
+### `v1.35.0`
+
+#### Features
+* Add extended attributes for manual macro spans [#517](https://github.com/newrelic/elixir_agent/pull/517)
+
+#### Fixes
+* Fix bandit duration with exception [#524](https://github.com/newrelic/elixir_agent/pull/524)
+* Fix bandit error reporting [#523](https://github.com/newrelic/elixir_agent/pull/523)
+
+#### Tweaks
+* Increase resolution of finch request duration [#518](https://github.com/newrelic/elixir_agent/pull/518)
+
+------
+
 ### `v1.34.0`
 
 #### Fixes
diff --git a/VERSION b/VERSION
index 2b17ffd..2aeaa11 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-1.34.0
+1.35.0


Test patch:
diff --git a/test/custom_event_test.exs b/test/custom_event_test.exs
index d3b7b3b..71d48ee 100644
--- a/test/custom_event_test.exs
+++ b/test/custom_event_test.exs
@@ -110,15 +110,8 @@ defmodule CustomEventTest do
 
     metrics = TestHelper.gather_harvest(Collector.Metric.Harvester)
 
-    assert TestHelper.find_metric(
-             metrics,
-             "Supportability/Elixir/Collector/HarvestSeen/CustomEventData"
-           )
-
-    assert TestHelper.find_metric(
-             metrics,
-             "Supportability/Elixir/Collector/HarvestSize/CustomEventData"
-           )
+    assert TestHelper.find_metric(metrics, "Supportability/Elixir/Collector/HarvestSeen/CustomEventData", :any)
+    assert TestHelper.find_metric(metrics, "Supportability/Elixir/Collector/HarvestSize/CustomEventData")
   end
 
   test "Handle non-serializable attribute values" do
diff --git a/test/support/test_helper.ex b/test/support/test_helper.ex
index 03d534d..51f4fd6 100644
--- a/test/support/test_helper.ex
+++ b/test/support/test_helper.ex
@@ -47,6 +47,13 @@ defmodule TestHelper do
     end)
   end
 
+  def find_metric(metrics, name, :any) do
+    Enum.find(metrics, fn
+      [%{name: ^name, scope: ""}, [_, _, _, _, _, _]] -> true
+      _ -> false
+    end)
+  end
+
   def find_metric(metrics, name, call_count) do
     Enum.find(metrics, fn
       [%{name: ^name, scope: ""}, [^call_count, _, _, _, _, _]] -> true
Repository: newrelic/elixir_agent
Pull request #531 (2025-05-29 21:16:36)

Add spans for phoenix controller view rendering
This PR adds spans for Phoenix Controller view rendering. Should help identify what work is done inside the rendering of a view.


Patch:
diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml
index a4ce157..c18f663 100644
--- a/.github/workflows/elixir.yml
+++ b/.github/workflows/elixir.yml
@@ -1,4 +1,6 @@
 name: CI
+permissions:
+  contents: read
 
 on:
   push:
diff --git a/lib/new_relic/telemetry/phoenix.ex b/lib/new_relic/telemetry/phoenix.ex
index ecbc22b..bad679b 100644
--- a/lib/new_relic/telemetry/phoenix.ex
+++ b/lib/new_relic/telemetry/phoenix.ex
@@ -1,6 +1,8 @@
 defmodule NewRelic.Telemetry.Phoenix do
   use GenServer
 
+  alias NewRelic.Tracer
+
   @moduledoc """
   Provides `Phoenix` instrumentation via `telemetry`.
 
@@ -20,10 +22,14 @@ defmodule NewRelic.Telemetry.Phoenix do
   end
 
   @phoenix_router_start [:phoenix, :router_dispatch, :start]
+  @phoenix_controller_render_start [:phoenix, :controller, :render, :start]
+  @phoenix_controller_render_stop [:phoenix, :controller, :render, :stop]
   @phoenix_error [:phoenix, :error_rendered]
 
   @phoenix_events [
     @phoenix_router_start,
+    @phoenix_controller_render_start,
+    @phoenix_controller_render_stop,
     @phoenix_error
   ]
 
@@ -83,6 +89,33 @@ defmodule NewRelic.Telemetry.Phoenix do
     |> NewRelic.add_attributes()
   end
 
+  def handle_event(
+        @phoenix_controller_render_start,
+        meas,
+        %{view: view, template: template, format: format} = meta,
+        _config
+      ) do
+    Tracer.Direct.start_span(
+      meta.telemetry_span_context,
+      "#{inspect(view)}.show",
+      system_time: meas.system_time,
+      attributes: [
+        "phoenix.view": inspect(view),
+        "phoenix.template": template,
+        "phoenix.format": format
+      ]
+    )
+  end
+
+  def handle_event(
+        @phoenix_controller_render_stop,
+        meas,
+        meta,
+        _config
+      ) do
+    Tracer.Direct.stop_span(meta.telemetry_span_context, duration: meas.duration)
+  end
+
   def handle_event(_event, _measurements, _meta, _config) do
     :ignore
   end


Test patch:
diff --git a/examples/apps/phx_example/test/phx_example_test.exs b/examples/apps/phx_example/test/phx_example_test.exs
index 04d67e1..8f21458 100644
--- a/examples/apps/phx_example/test/phx_example_test.exs
+++ b/examples/apps/phx_example/test/phx_example_test.exs
@@ -90,9 +90,11 @@ defmodule PhxExampleTest do
         tx_span = TestHelper.find_event(span_events, "/Phoenix/PhxExampleWeb.HomeLive/index")
         process_span = TestHelper.find_event(span_events, "Transaction Root Process")
         mount_span = TestHelper.find_event(span_events, "PhxExampleWeb.HomeLive:index.mount")
+        render_span = TestHelper.find_event(span_events, "PhxExampleWeb.Layouts.show")
 
         assert process_span[:parentId] == tx_span[:guid]
         assert mount_span[:"live_view.params"]
+        assert render_span[:"phoenix.view"]
       end
 
       @endpoint PhxExampleWeb.Endpoint
Repository: dashbitco/nimble_options
Pull request #34 (2020-05-11 16:46:56)

Add pid type
Hello! I was looking to use this library in a project of mine, but one of the types I'm passing is a PID. 

This PR adds `:pid` to possible types. I *think* I've updated all of the documentation and added the correct tests. Please let me know if I missed something!

Edit: I also wasn't sure if I should update the changelog, or if that only got updated when a release went out.


Patch:
diff --git a/lib/nimble_options.ex b/lib/nimble_options.ex
index 9b6e48f..9f201e0 100644
--- a/lib/nimble_options.ex
+++ b/lib/nimble_options.ex
@@ -89,6 +89,8 @@ defmodule NimbleOptions do
 
     * `:timeout` - A non-negative integer or the atom `:infinity`.
 
+    * `:pid` - A PID (process identifier).
+
     * `:mfa` - A named function in the format `{module, function, arity}`
 
     * `:mod_arg` - A module along with arguments, e.g. `{MyModule, [arg1, arg2]}`.
@@ -172,7 +174,8 @@ defmodule NimbleOptions do
     :mod_arg,
     :string,
     :boolean,
-    :timeout
+    :timeout,
+    :pid
   ]
 
   @type schema() :: keyword()
@@ -384,6 +387,14 @@ defmodule NimbleOptions do
     end
   end
 
+  defp validate_type(:pid, _key, value) when is_pid(value) do
+    :ok
+  end
+
+  defp validate_type(:pid, key, value) do
+    {:error, "expected #{inspect(key)} to be a pid, got: #{inspect(value)}"}
+  end
+
   defp validate_type(:mfa, _key, {m, f, args}) when is_atom(m) and is_atom(f) and is_list(args) do
     :ok
   end


Test patch:
diff --git a/test/nimble_options_test.exs b/test/nimble_options_test.exs
index 77c54e9..70592a3 100644
--- a/test/nimble_options_test.exs
+++ b/test/nimble_options_test.exs
@@ -30,7 +30,7 @@ defmodule NimbleOptionsTest do
 
       Available types: :any, :keyword_list, :non_empty_keyword_list, :atom, \
       :non_neg_integer, :pos_integer, :mfa, :mod_arg, :string, :boolean, :timeout, \
-      {:fun, arity}, {:one_of, choices}, {:custom, mod, fun, args}\
+      :pid, {:fun, arity}, {:one_of, choices}, {:custom, mod, fun, args}\
       """
 
       assert_raise ArgumentError, message, fn ->
@@ -262,6 +262,19 @@ defmodule NimbleOptionsTest do
                 "expected :timeout to be non-negative integer or :infinity, got: :invalid"}
     end
 
+    test "valid pid" do
+      schema = [name: [type: :pid]]
+      opts = [name: self()]
+      assert NimbleOptions.validate(opts, schema) == {:ok, opts}
+    end
+
+    test "invalid pid" do
+      schema = [name: [type: :pid]]
+
+      assert NimbleOptions.validate([name: 1], schema) ==
+               {:error, "expected :name to be a pid, got: 1"}
+    end
+
     test "valid mfa" do
       schema = [transformer: [type: :mfa]]
Repository: dashbitco/nimble_options
Pull request #53 (2020-10-26 10:24:42)

Fix indentation in docs for nested schemas


Patch:
diff --git a/lib/nimble_options/docs.ex b/lib/nimble_options/docs.ex
index e6599fe..79c821e 100644
--- a/lib/nimble_options/docs.ex
+++ b/lib/nimble_options/docs.ex
@@ -57,7 +57,8 @@ defmodule NimbleOptions.Docs do
         build_docs_with_subsection(schema[:subsection], schema[:keys], {docs, sections, level})
 
       schema[:keys] ->
-        build_docs(schema[:keys], {docs, sections, level + 1})
+        {docs, sections, _level} = build_docs(schema[:keys], {docs, sections, level + 1})
+        {docs, sections, level}
 
       true ->
         {docs, sections, level}


Test patch:
diff --git a/test/nimble_options_test.exs b/test/nimble_options_test.exs
index 2ed6a06..e78430f 100644
--- a/test/nimble_options_test.exs
+++ b/test/nimble_options_test.exs
@@ -1023,7 +1023,8 @@ defmodule NimbleOptionsTest do
               ]
             ]
           ]
-        ]
+        ],
+        other_key: [type: :string]
       ]
 
       docs = """
@@ -1037,6 +1038,8 @@ defmodule NimbleOptionsTest do
 
             * `:interval` - Required. The interval.
 
+        * `:other_key`
+
       """
 
       assert NimbleOptions.docs(schema) == docs
@@ -1059,7 +1062,8 @@ defmodule NimbleOptionsTest do
             module: [type: :mod_arg, doc: "The module."],
             concurrency: [type: :pos_integer, doc: "The concurrency."]
           ]
-        ]
+        ],
+        other_key: [type: :string]
       ]
 
       docs = """
@@ -1067,6 +1071,8 @@ defmodule NimbleOptionsTest do
 
         * `:producer` - This is the producer summary. See "Producers options" section below.
 
+        * `:other_key`
+
       ### Producers options
 
       The producer options allow users to set up the producer.
Repository: dashbitco/nimble_options
Pull request #61 (2021-01-25 20:42:16)

Fix docs generation when custom key type has no keys
Fixes https://github.com/dashbitco/nimble_options/issues/60.

coveralls: ## Pull Request Test Coverage Report for [Build 5a513cdf4483550a0038fd5581ce5022707b6a35-PR-61](https://coveralls.io/builds/36583190)

* **1** of **1**   **(100.0%)**  changed or added relevant line in **1** file are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **98.45%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/36583190/badge)](https://coveralls.io/builds/36583190) |
| :-- | --: |
| Change from base [Build a88440f328e10d9e5aefa81fec033cd5f1ae15de](https://coveralls.io/builds/35326008): |  0.0% |
| Covered Lines: | 127 |
| Relevant Lines: | 129 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/lib/nimble_options/docs.ex b/lib/nimble_options/docs.ex
index 7a6400a..063bc24 100644
--- a/lib/nimble_options/docs.ex
+++ b/lib/nimble_options/docs.ex
@@ -18,7 +18,7 @@ defmodule NimbleOptions.Docs do
     if schema[:*] do
       build_docs(schema[:*][:keys], acc)
     else
-      Enum.reduce(schema, {docs, sections, level}, &maybe_option_doc/2)
+      Enum.reduce(schema || [], {docs, sections, level}, &maybe_option_doc/2)
     end
   end
 


Test patch:
diff --git a/test/nimble_options_test.exs b/test/nimble_options_test.exs
index 8022e13..5c87bf3 100644
--- a/test/nimble_options_test.exs
+++ b/test/nimble_options_test.exs
@@ -1472,6 +1472,25 @@ defmodule NimbleOptionsTest do
 
       assert NimbleOptions.docs(schema) == docs
     end
+
+    test "stop generating docs recursively if type has no :keys" do
+      schema = [
+        custom_keys: [
+          type: :keyword_list,
+          doc: "Custom keys",
+          keys: [*: [type: :atom, doc: "Won't be there!"]]
+        ]
+      ]
+
+      opts = [custom_keys: [key1: :a, key2: :b]]
+
+      assert {:ok, ^opts} = NimbleOptions.validate(opts, schema)
+
+      assert NimbleOptions.docs(schema) == """
+               * `:custom_keys` - Custom keys
+
+             """
+    end
   end
 
   describe "validate!/2 (raising version)" do
Repository: dashbitco/nimble_options
Pull request #63 (2021-04-16 11:23:50)

Add float type
I was a bit surprised that float is not available as a basic type. So, here it is.


Patch:
diff --git a/lib/nimble_options.ex b/lib/nimble_options.ex
index 1ab5c3a..9f0c7ed 100644
--- a/lib/nimble_options.ex
+++ b/lib/nimble_options.ex
@@ -91,6 +91,8 @@ defmodule NimbleOptions do
 
     * `:pos_integer` - A positive integer.
 
+    * `:float` - A float.
+
     * `:timeout` - A non-negative integer or the atom `:infinity`.
 
     * `:pid` - A PID (process identifier).
@@ -198,6 +200,7 @@ defmodule NimbleOptions do
     :integer,
     :non_neg_integer,
     :pos_integer,
+    :float,
     :mfa,
     :mod_arg,
     :string,
@@ -411,6 +414,10 @@ defmodule NimbleOptions do
     )
   end
 
+  defp validate_type(:float, key, value) when not is_float(value) do
+    error_tuple(key, value, "expected #{inspect(key)} to be a float, got: #{inspect(value)}")
+  end
+
   defp validate_type(:atom, key, value) when not is_atom(value) do
     error_tuple(key, value, "expected #{inspect(key)} to be an atom, got: #{inspect(value)}")
   end


Test patch:
diff --git a/test/nimble_options_test.exs b/test/nimble_options_test.exs
index 5c87bf3..0540d43 100644
--- a/test/nimble_options_test.exs
+++ b/test/nimble_options_test.exs
@@ -40,7 +40,7 @@ defmodule NimbleOptionsTest do
       Reason: invalid option type :foo.
 
       Available types: :any, :keyword_list, :non_empty_keyword_list, :atom, \
-      :integer, :non_neg_integer, :pos_integer, :mfa, :mod_arg, :string, :boolean, :timeout, \
+      :integer, :non_neg_integer, :pos_integer, :float, :mfa, :mod_arg, :string, :boolean, :timeout, \
       :pid, {:fun, arity}, {:in, choices}, {:or, subtypes}, {:custom, mod, fun, args}, \
       {:list, subtype} \
       (in options [:stages])\
@@ -286,6 +286,33 @@ defmodule NimbleOptionsTest do
                 }}
     end
 
+    test "valid float" do
+      schema = [certainty: [type: :float]]
+      opts = [certainty: 0.5]
+
+      assert NimbleOptions.validate(opts, schema) == {:ok, opts}
+    end
+
+    test "invalid float" do
+      schema = [certainty: [type: :float]]
+
+      assert NimbleOptions.validate([certainty: 1], schema) ==
+               {:error,
+                %ValidationError{
+                  key: :certainty,
+                  value: 1,
+                  message: "expected :certainty to be a float, got: 1"
+                }}
+
+      assert NimbleOptions.validate([certainty: :an_atom], schema) ==
+               {:error,
+                %ValidationError{
+                  key: :certainty,
+                  value: :an_atom,
+                  message: "expected :certainty to be a float, got: :an_atom"
+                }}
+    end
+
     test "valid atom" do
       schema = [name: [type: :atom]]
       opts = [name: :an_atom]
Repository: dashbitco/nimble_options
Pull request #71 (2021-10-15 18:28:02)

add `Range` support for `{:in, choices}` type
Ranges implement Enumerable and support `in`, so you should be able to
use them with the `{:in, choices}` type.

For example, to check if a value is a byte:

```elixir
schema = [decimals: [type: {:in, 0..255}]]
```

This commit adds that support.

dcrck: added some tests

Patch:
diff --git a/lib/nimble_options.ex b/lib/nimble_options.ex
index 1202a00..4d1d4ba 100644
--- a/lib/nimble_options.ex
+++ b/lib/nimble_options.ex
@@ -106,9 +106,9 @@ defmodule NimbleOptions do
     * `{:fun, arity}` - Any function with the specified arity.
 
     * `{:in, choices}` - A value that is a member of one of the `choices`. `choices`
-      should be a list of terms. The value is an element in said list of terms,
-      that is, `value in choices` is `true`. This was previously called `:one_of` and
-      the `:in` name is available since version 0.3.3.
+      should be a list of terms or a `Range`. The value is an element in said
+      list of terms, that is, `value in choices` is `true`. This was previously
+      called `:one_of` and the `:in` name is available since version 0.3.3.
 
     * `{:custom, mod, fun, args}` - A custom type. The related value must be validated
       by `mod.fun(values, ...args)`. The function should return `{:ok, value}` or
@@ -727,6 +727,10 @@ defmodule NimbleOptions do
     {:ok, value}
   end
 
+  def validate_type({:in, _first.._last} = value) do
+    {:ok, value}
+  end
+
   def validate_type({:custom, mod, fun, args} = value)
       when is_atom(mod) and is_atom(fun) and is_list(args) do
     {:ok, value}


Test patch:
diff --git a/test/nimble_options_test.exs b/test/nimble_options_test.exs
index 49d7b6a..9338e02 100644
--- a/test/nimble_options_test.exs
+++ b/test/nimble_options_test.exs
@@ -572,6 +572,19 @@ defmodule NimbleOptionsTest do
       assert NimbleOptions.validate(opts, schema) == {:ok, opts}
     end
 
+    test "valid {:in, choices} with Range" do
+      schema = [decimals: [type: {:in, 0..255}]]
+
+      opts = [decimals: 0]
+      assert NimbleOptions.validate(opts, schema) == {:ok, opts}
+
+      opts = [decimals: 100]
+      assert NimbleOptions.validate(opts, schema) == {:ok, opts}
+
+      opts = [decimals: 255]
+      assert NimbleOptions.validate(opts, schema) == {:ok, opts}
+    end
+
     test "invalid {:in, choices}" do
       schema = [batch_mode: [type: {:in, [:flush, :bulk]}]]
 
@@ -586,6 +599,20 @@ defmodule NimbleOptionsTest do
                 }}
     end
 
+    test "invalid {:in, choices} with Range" do
+      schema = [decimals: [type: {:in, 0..255}]]
+
+      opts = [decimals: -1]
+
+      assert NimbleOptions.validate(opts, schema) ==
+               {:error,
+                %ValidationError{
+                  key: :decimals,
+                  value: -1,
+                  message: "expected :decimals to be one of 0..255, got: -1"
+                }}
+    end
+
     test "deprecation of {:one_of, choices}" do
       schema = [batch_mode: [type: {:one_of, [:flush, :bulk]}]]