ecoportal-api-v2 3.3.5 → 3.3.6
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 +4 -4
- data/CHANGELOG.md +36 -2
- data/README.md +52 -2
- data/lib/ecoportal/api/common/concerns/benchmarkable.rb +30 -5
- data/lib/ecoportal/api/v2_version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8804921ca6b6893fba5d2f775b2718bcbd8c7e23e840224ea792f8a11265951d
|
|
4
|
+
data.tar.gz: e0c1c47bd24c02bce9c729b3a5ac67bf246e07e726d9f218ae093ff4d5dfb1a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 186d61f92d3d47212eb80bc16dc59b83d3fa2bd9c030c353e8098b837759a33464b6edb59d15842f69e797ae5d46a0a193d251ff5b28fd6bc9ff54aa64b9f418
|
|
7
|
+
data.tar.gz: b5741a4223c50560cff05dfa95f87e718b540016fb10faf5190998af91bac4ddbb0f12dea2a63c7fe35305e95976480f086da0beff52435d4f89237c6affa25f
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [3.3.6] - 2026-09-30
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **`Benchmarkable#memory_usage` crashed with `NoMethodError: undefined method 'chop' for nil`
|
|
10
|
+
on modern Windows.** The Windows branch shelled out to `wmic`, which has been deprecated and
|
|
11
|
+
removed from current Windows (Win 11 24H2 / Server 2025). A backtick to a missing command
|
|
12
|
+
returns an EMPTY string, not `nil`, so the `return 0 unless wmem` guard never fired;
|
|
13
|
+
`"".lines.first` is `nil`, and `nil.chop` raised. Because benchmarking wraps ordinary
|
|
14
|
+
operations (e.g. every `graphql.pages.get` in downstream `ecoportal-api-graphql`/`eco-helpers`
|
|
15
|
+
flows), the crash surfaced as a bogus "page not found" on EVERY page fetch on such a host,
|
|
16
|
+
with no real relation to the page or its permissions. `memory_usage` now guards nil AND empty,
|
|
17
|
+
falls back to `Get-CimInstance` (`wmic`'s PowerShell successor), and returns 0 when no reading
|
|
18
|
+
is available -- benchmarking never crashes the operation it wraps. Adds
|
|
19
|
+
`spec/ecoportal/api/common/concerns/benchmarkable_spec.rb` pinning the never-raise invariant
|
|
20
|
+
and the empty-`wmic`-output case.
|
|
21
|
+
|
|
22
|
+
- **`spec.files` allowlisted by root directory, not by full path.** The `3.3.4` fix replaced a
|
|
23
|
+
denylist with `f.start_with?('lib/', 'exe/')`, which stops a new top-level directory from
|
|
24
|
+
shipping but says nothing about what a file under `lib/` actually IS. `ecoportal-api-graphql`
|
|
25
|
+
hit exactly that blind spot in its `2.2.0` build, shipping five `CLAUDE.md` files that lived
|
|
26
|
+
inside its `lib/` tree under the equivalent rule. This gem was never caught leaking that way --
|
|
27
|
+
`git ls-files lib/ | grep -v '\.rb$'` is empty today -- but the same root-keyed rule sat here
|
|
28
|
+
too, so it is hardened pre-emptively rather than waiting for its own incident: `spec.files` now
|
|
29
|
+
requires both the `lib/` prefix and a `.rb` extension, still intersected with `git ls-files`.
|
|
30
|
+
Adds `spec/packaging_spec.rb` to pin the allowlist against regression.
|
|
31
|
+
|
|
32
|
+
### Security
|
|
33
|
+
|
|
34
|
+
- Removes customer and internal identifiers from this changelog (shipped code comments re-scanned: clean). The
|
|
35
|
+
published `3.3.4` and `3.3.5` changelogs named a customer, and `3.3.2` shipped an internal
|
|
36
|
+
notes file; `3.3.6` is the clean replacement so those versions can be yanked. No code or
|
|
37
|
+
dependency change beyond the fixes above -- drop-in for `~> 3.3, >= 3.3.5`.
|
|
38
|
+
|
|
5
39
|
## [3.3.5] - 2026-08-20
|
|
6
40
|
|
|
7
41
|
### Fixed
|
|
@@ -31,7 +65,7 @@ All notable changes to this project will be documented in this file.
|
|
|
31
65
|
### Fixed
|
|
32
66
|
|
|
33
67
|
- Packaging-only republish with the allowlisted gemspec. `3.3.3` shipped internal repository
|
|
34
|
-
content (
|
|
68
|
+
content (internal AI-tooling notes and editor settings) to rubygems.org via the
|
|
35
69
|
old denylist `spec.files`. `3.3.4` is the identical `lib/` code packaged clean; `3.3.3` will
|
|
36
70
|
be yanked.
|
|
37
71
|
|
|
@@ -45,7 +79,7 @@ All notable changes to this project will be documented in this file.
|
|
|
45
79
|
`(attribute, obj_k)` destructured the **accumulator hash** and `attribute` became the trace `Hash` →
|
|
46
80
|
`send(<hash>)` raised `"… is not a symbol nor a string" (TypeError)` on **any** cascaded operation
|
|
47
81
|
(e.g. `Diffable#as_update` / `DiffService`) over a model with nested attributes. Latent because
|
|
48
|
-
Ruby 2.x tolerated the arg order; fatal under Ruby 3.x (crashed
|
|
82
|
+
Ruby 2.x tolerated the arg order; fatal under Ruby 3.x (crashed a live customer integration
|
|
49
83
|
via the `ecoportal-api-graphql` consumer). Swapped to `|(attribute, obj_k), out|` (commit `6a2b1b5`).
|
|
50
84
|
**Regression spec added** (`spec/…/double_model_spec.rb`).
|
|
51
85
|
|
data/README.md
CHANGED
|
@@ -1,7 +1,57 @@
|
|
|
1
1
|
# Ecoportal::API::V2
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
## Why this repo exists
|
|
4
|
+
|
|
5
|
+
This gem holds the **base models for GraphQL** -- the `DoubleModel` / `CollectionModel`
|
|
6
|
+
class-holder layer under `lib/ecoportal/api/common/content/` -- and it is
|
|
7
|
+
`ecoportal-api-graphql`'s pinned runtime dependency: its `Common::GraphQL::Model`
|
|
8
|
+
subclasses `Ecoportal::API::Common::Content::DoubleModel` directly.
|
|
9
|
+
|
|
10
|
+
In the owner's words (2026-09-24):
|
|
11
|
+
|
|
12
|
+
> "contains base models for GraphQL and must be documented, but excluding the api_v2
|
|
13
|
+
> part... as that is deprecated... this gem will become a DoubleModel class holder gem
|
|
14
|
+
> once we removed all the APIv2 stuff... and we will repurpose the repo :)"
|
|
15
|
+
|
|
16
|
+
### What stays and matters
|
|
17
|
+
|
|
18
|
+
The `Ecoportal::API::Common::Content` base-model infrastructure, under
|
|
19
|
+
`lib/ecoportal/api/common/content/`:
|
|
20
|
+
|
|
21
|
+
- `DoubleModel` -- the foundational two-layer (live doc + patch doc) model abstraction;
|
|
22
|
+
almost all V2 models, and `ecoportal-api-graphql`'s `Common::GraphQL::Model`, inherit
|
|
23
|
+
from it.
|
|
24
|
+
- `CollectionModel` / `ArrayModel` -- ordered collections with upsert/delete/mutation
|
|
25
|
+
support.
|
|
26
|
+
- `ClassHelpers`, `DocHelpers`, `ModelHelpers`, `IncluderHelpers` -- supporting mixins
|
|
27
|
+
for model construction.
|
|
28
|
+
|
|
29
|
+
### Deprecated -- do not build on
|
|
30
|
+
|
|
31
|
+
The `Ecoportal::API::V2` REST client namespace (`lib/ecoportal/api/v2/`: `page`,
|
|
32
|
+
`pages`, `people`, `registers`, `s3`) is the APIv2 REST client. It is **deprecated** and
|
|
33
|
+
being removed. Once it is gone, this gem becomes a pure `DoubleModel` class-holder gem
|
|
34
|
+
and the repo will be repurposed (name/scope not yet decided by the owner). The owner
|
|
35
|
+
flagged the same likely fate, tentatively, for `ecoportal-api` (its v0/v1 APIs are
|
|
36
|
+
deprecated and due to retire soon) -- not yet ruled, and out of scope here.
|
|
37
|
+
|
|
38
|
+
### Who uses it
|
|
39
|
+
|
|
40
|
+
`ecoportal-api-graphql` depends on this gem for its base-model layer; `eco-helpers`
|
|
41
|
+
(the team's central integrations library) sits downstream of both.
|
|
42
|
+
|
|
43
|
+
```mermaid
|
|
44
|
+
flowchart LR
|
|
45
|
+
A["ecoportal-api-v2<br/>Common::Content::DoubleModel"] --> B[ecoportal-api-graphql]
|
|
46
|
+
B --> C[eco-helpers]
|
|
47
|
+
```
|
|
48
|
+
*Source: `CLAUDE.md` dependency chain + owner ruling, 2026-09-24.*
|
|
49
|
+
|
|
50
|
+
### Current state
|
|
51
|
+
|
|
52
|
+
The APIv2 client removal and repo repurposing have not started; this section records
|
|
53
|
+
intent so the owner does not need to re-explain it. See `TODO.md` (`DOC-ROADMAP-1`,
|
|
54
|
+
`DOC-WHY-1`) for the tracked work.
|
|
5
55
|
|
|
6
56
|
## Installation
|
|
7
57
|
|
|
@@ -156,17 +156,42 @@ module Ecoportal
|
|
|
156
156
|
[parts[..-2].join(", "), parts.last].join(" and ")
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
-
# @
|
|
159
|
+
# @note Benchmarking must never crash the operation it wraps. When a memory
|
|
160
|
+
# reading cannot be obtained -- most notably on modern Windows, where `wmic`
|
|
161
|
+
# has been deprecated and removed (Win 11 24H2 / Server 2025) -- this returns
|
|
162
|
+
# 0 rather than raising. A failed backtick spawn yields an EMPTY string (not
|
|
163
|
+
# nil), so a bare `unless wmem` never guarded it and `"".lines.first` was nil,
|
|
164
|
+
# raising `NoMethodError: undefined method 'chop' for nil` on every wrapped call.
|
|
165
|
+
# @return [Float, Integer] total memory used by this process in KB, or 0 when unavailable
|
|
160
166
|
def memory_usage
|
|
161
167
|
if Gem.win_platform?
|
|
162
|
-
|
|
163
|
-
return 0 unless wmem
|
|
164
|
-
|
|
165
|
-
wmem.lines.first.chop.strip.to_i / 1024.0
|
|
168
|
+
windows_memory_usage
|
|
166
169
|
else
|
|
167
170
|
`ps -o rss= -p #{Process.pid}`.to_i
|
|
168
171
|
end
|
|
169
172
|
end
|
|
173
|
+
|
|
174
|
+
# Windows working-set in KB. Tries `wmic` (legacy) then `Get-CimInstance`
|
|
175
|
+
# (its PowerShell successor); returns 0 if neither is available. Never raises.
|
|
176
|
+
# @return [Float, Integer]
|
|
177
|
+
def windows_memory_usage
|
|
178
|
+
bytes = windows_working_set_bytes
|
|
179
|
+
bytes.positive? ? bytes / 1024.0 : 0
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# @return [Integer] process working-set size in bytes, or 0 when unavailable
|
|
183
|
+
def windows_working_set_bytes
|
|
184
|
+
wmem = `wmic process where processid=#{Process.pid} get WorkingSetSize 2>NUL | findstr "[0-9]"`
|
|
185
|
+
line = wmem.to_s.lines.first
|
|
186
|
+
return line.strip.to_i if line && !line.strip.empty?
|
|
187
|
+
|
|
188
|
+
filter = "ProcessId=#{Process.pid}"
|
|
189
|
+
cmd = "(Get-CimInstance Win32_Process -Filter '#{filter}').WorkingSetSize"
|
|
190
|
+
ps = `powershell -NoProfile -Command "#{cmd}" 2>NUL`
|
|
191
|
+
ps.to_s.strip.to_i
|
|
192
|
+
rescue StandardError
|
|
193
|
+
0
|
|
194
|
+
end
|
|
170
195
|
end
|
|
171
196
|
end
|
|
172
197
|
end
|