Skip to content

Commit 74675ee

Browse files
release: 0.5.1 (#9)
* codegen metadata * chore: add scripts * fix: use correct user agent value * codegen metadata * codegen metadata * feat: Initialize volume with data * chore: update dependencies * feat: fix edge cases for sending request data and add YAML support * fix: fix for default flag values * feat: Ingress * codegen metadata * feat(api): manual updates * release: 0.5.1 * fix our custom commands for stainless changes --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> Co-authored-by: Rafael Garcia <[email protected]>
1 parent a98d7ea commit 74675ee

31 files changed

+1972
-496
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.5.0"
2+
".": "0.5.1"
33
}

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 18
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-ce51f144a3d2de556750203edbaa5bfeefe874660737c35a4fc37dfb30057dd5.yml
3-
openapi_spec_hash: 27663b6503056317abcb578ac7b67c06
4-
config_hash: b4e65d240d7bca1ba6162ee2098c8ac2
1+
configured_endpoints: 22
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-da3f4038bb544acae375f44527f515dc58308f67822905258b155192041e65ed.yml
3+
openapi_spec_hash: 4c7f6f453c20eda7fd8689e8917c65f9
4+
config_hash: a7d0557c72de54fd6baded5b189777c3

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
# Changelog
22

3+
## 0.5.1 (2025-12-05)
4+
5+
Full Changelog: [v0.5.0...v0.5.1](https://github.com/onkernel/hypeman-cli/compare/v0.5.0...v0.5.1)
6+
7+
### Features
8+
9+
* **api:** manual updates ([a3f2ec1](https://github.com/onkernel/hypeman-cli/commit/a3f2ec15101a6afd6feb1da1addcb3a2589acb53))
10+
* fix edge cases for sending request data and add YAML support ([3e740a9](https://github.com/onkernel/hypeman-cli/commit/3e740a94698f4704e79cc5c3b6434cbb1bfcb935))
11+
* Ingress ([bfb79c5](https://github.com/onkernel/hypeman-cli/commit/bfb79c5a160a3b92cac3793ea49da49ddcc7c8c6))
12+
* Initialize volume with data ([ef9997c](https://github.com/onkernel/hypeman-cli/commit/ef9997cc2c6d0fc14531bdf9d1238f3447e3a454))
13+
* **push:** add hypeman push command for local image upload ([e120ec6](https://github.com/onkernel/hypeman-cli/commit/e120ec6d96531ab49909a3d55895f5fcc4d43dc2))
14+
* respect HYPEMAN_BASE_URL environment variable ([17122d7](https://github.com/onkernel/hypeman-cli/commit/17122d7b2d6041c57d4e2d341b52f18697aef5d4))
15+
16+
17+
### Bug Fixes
18+
19+
* fix for default flag values ([812e009](https://github.com/onkernel/hypeman-cli/commit/812e0091f73ab5e8992adab5ca1c2cef76b60c63))
20+
* **run:** wait for image to be ready before creating instance ([048ee73](https://github.com/onkernel/hypeman-cli/commit/048ee7311c39d6c3c7efad9c662fa2a1993ced97))
21+
* use correct user agent value ([580e468](https://github.com/onkernel/hypeman-cli/commit/580e468e95a11c8c57016954464039af3b0586f1))
22+
23+
24+
### Chores
25+
26+
* add scripts ([c3e4955](https://github.com/onkernel/hypeman-cli/commit/c3e4955f932edc7567d929f22f3e93f22ae69e1a))
27+
* update dependencies ([4ed31f6](https://github.com/onkernel/hypeman-cli/commit/4ed31f6294c1b94ef764bb7959dc99e89af62cfb))
28+
329
## 0.5.0 (2025-11-26)
430

531
Full Changelog: [v0.4.0...v0.5.0](https://github.com/onkernel/hypeman-cli/compare/v0.4.0...v0.5.0)

go.mod

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ require (
77
github.com/charmbracelet/bubbletea v1.3.6
88
github.com/charmbracelet/lipgloss v1.1.0
99
github.com/charmbracelet/x/term v0.2.1
10+
github.com/goccy/go-yaml v1.18.0
1011
github.com/google/go-containerregistry v0.20.7
1112
github.com/gorilla/websocket v1.5.3
1213
github.com/itchyny/json2yaml v0.1.4
1314
github.com/muesli/reflow v0.3.0
14-
github.com/onkernel/hypeman-go v0.4.0
15+
github.com/onkernel/hypeman-go v0.5.0
1516
github.com/tidwall/gjson v1.18.0
1617
github.com/tidwall/pretty v1.2.1
1718
github.com/tidwall/sjson v1.2.5
@@ -21,10 +22,8 @@ require (
2122
)
2223

2324
require (
24-
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
2525
github.com/Microsoft/go-winio v0.6.2 // indirect
2626
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
27-
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
2827
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
2928
github.com/charmbracelet/x/ansi v0.9.3 // indirect
3029
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
@@ -43,14 +42,14 @@ require (
4342
github.com/felixge/httpsnoop v1.0.4 // indirect
4443
github.com/go-logr/logr v1.4.3 // indirect
4544
github.com/go-logr/stdr v1.2.2 // indirect
45+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
4646
github.com/klauspost/compress v1.18.1 // indirect
4747
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
4848
github.com/mattn/go-isatty v0.0.20 // indirect
4949
github.com/mattn/go-localereader v0.0.1 // indirect
5050
github.com/mattn/go-runewidth v0.0.16 // indirect
5151
github.com/mitchellh/go-homedir v1.1.0 // indirect
5252
github.com/moby/docker-image-spec v1.3.1 // indirect
53-
github.com/moby/sys/sequential v0.6.0 // indirect
5453
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
5554
github.com/muesli/cancelreader v0.2.2 // indirect
5655
github.com/muesli/termenv v0.16.0 // indirect
@@ -66,15 +65,12 @@ require (
6665
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
6766
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
6867
go.opentelemetry.io/otel v1.38.0 // indirect
69-
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
7068
go.opentelemetry.io/otel/metric v1.38.0 // indirect
71-
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
72-
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
7369
go.opentelemetry.io/otel/trace v1.38.0 // indirect
74-
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
75-
golang.org/x/net v0.47.0 // indirect
7670
golang.org/x/sync v0.18.0 // indirect
7771
golang.org/x/sys v0.38.0 // indirect
7872
golang.org/x/text v0.31.0 // indirect
79-
google.golang.org/protobuf v1.36.10 // indirect
73+
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
74+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
75+
google.golang.org/grpc v1.75.1 // indirect
8076
)

go.sum

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
6060
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
6161
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
6262
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
63+
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
64+
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
6365
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
6466
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
6567
github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I=
@@ -103,8 +105,8 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
103105
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
104106
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
105107
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
106-
github.com/onkernel/hypeman-go v0.4.0 h1:3zDpB/WOPhkdJ/Lug3DmBDUcGR5zHwpOTzLEbsO4AnE=
107-
github.com/onkernel/hypeman-go v0.4.0/go.mod h1:pxRRFfVcLvafZpDD1O6IjwHnem3hKEuZTCClrnGiIKA=
108+
github.com/onkernel/hypeman-go v0.5.0 h1:ILe+n18aN5MXx0ARxDJ/ZYqcX2MdfJqWrE4sn14gJ5I=
109+
github.com/onkernel/hypeman-go v0.5.0/go.mod h1:BPT1yh0gbby1E+As/xLM3GVjw7752+2C5SaEiJV9rRc=
108110
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
109111
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
110112
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
@@ -169,7 +171,6 @@ golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
169171
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
170172
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
171173
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
172-
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
173174
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
174175
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
175176
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

internal/apiform/encoder.go

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
package apiform
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"mime/multipart"
7+
"net/textproto"
8+
"path"
9+
"reflect"
10+
"sort"
11+
"strconv"
12+
"strings"
13+
)
14+
15+
// Marshal encodes a value as multipart form data using default settings
16+
func Marshal(value any, writer *multipart.Writer) error {
17+
e := &encoder{
18+
format: FormatRepeat,
19+
}
20+
return e.marshal(value, writer)
21+
}
22+
23+
// MarshalWithSettings encodes a value with custom array format
24+
func MarshalWithSettings(value any, writer *multipart.Writer, arrayFormat FormFormat) error {
25+
e := &encoder{
26+
format: arrayFormat,
27+
}
28+
return e.marshal(value, writer)
29+
}
30+
31+
type encoder struct {
32+
format FormFormat
33+
}
34+
35+
func (e *encoder) marshal(value any, writer *multipart.Writer) error {
36+
val := reflect.ValueOf(value)
37+
if !val.IsValid() {
38+
return nil
39+
}
40+
return e.encodeValue("", val, writer)
41+
}
42+
43+
func (e *encoder) encodeValue(key string, val reflect.Value, writer *multipart.Writer) error {
44+
if !val.IsValid() {
45+
return writer.WriteField(key, "")
46+
}
47+
48+
t := val.Type()
49+
50+
if t.Implements(reflect.TypeOf((*io.Reader)(nil)).Elem()) {
51+
return e.encodeReader(key, val, writer)
52+
}
53+
54+
switch t.Kind() {
55+
case reflect.Pointer:
56+
if val.IsNil() || !val.IsValid() {
57+
return writer.WriteField(key, "")
58+
}
59+
return e.encodeValue(key, val.Elem(), writer)
60+
61+
case reflect.Slice, reflect.Array:
62+
return e.encodeArray(key, val, writer)
63+
64+
case reflect.Map:
65+
return e.encodeMap(key, val, writer)
66+
67+
case reflect.Interface:
68+
if val.IsNil() {
69+
return writer.WriteField(key, "")
70+
}
71+
return e.encodeValue(key, val.Elem(), writer)
72+
73+
case reflect.String:
74+
return writer.WriteField(key, val.String())
75+
76+
case reflect.Bool:
77+
if val.Bool() {
78+
return writer.WriteField(key, "true")
79+
}
80+
return writer.WriteField(key, "false")
81+
82+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
83+
return writer.WriteField(key, strconv.FormatInt(val.Int(), 10))
84+
85+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
86+
return writer.WriteField(key, strconv.FormatUint(val.Uint(), 10))
87+
88+
case reflect.Float32:
89+
return writer.WriteField(key, strconv.FormatFloat(val.Float(), 'f', -1, 32))
90+
91+
case reflect.Float64:
92+
return writer.WriteField(key, strconv.FormatFloat(val.Float(), 'f', -1, 64))
93+
94+
default:
95+
return fmt.Errorf("unknown type: %s", t.String())
96+
}
97+
}
98+
99+
func (e *encoder) encodeArray(key string, val reflect.Value, writer *multipart.Writer) error {
100+
if e.format == FormatComma {
101+
var values []string
102+
for i := 0; i < val.Len(); i++ {
103+
item := val.Index(i)
104+
var strValue string
105+
switch item.Kind() {
106+
case reflect.String:
107+
strValue = item.String()
108+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
109+
strValue = strconv.FormatInt(item.Int(), 10)
110+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
111+
strValue = strconv.FormatUint(item.Uint(), 10)
112+
case reflect.Float32, reflect.Float64:
113+
strValue = strconv.FormatFloat(item.Float(), 'f', -1, 64)
114+
case reflect.Bool:
115+
strValue = strconv.FormatBool(item.Bool())
116+
default:
117+
return fmt.Errorf("comma format not supported for complex array elements")
118+
}
119+
values = append(values, strValue)
120+
}
121+
return writer.WriteField(key, strings.Join(values, ","))
122+
}
123+
124+
for i := 0; i < val.Len(); i++ {
125+
var formattedKey string
126+
switch e.format {
127+
case FormatRepeat:
128+
formattedKey = key
129+
case FormatBrackets:
130+
formattedKey = key + "[]"
131+
case FormatIndicesDots:
132+
if key == "" {
133+
formattedKey = strconv.Itoa(i)
134+
} else {
135+
formattedKey = key + "." + strconv.Itoa(i)
136+
}
137+
case FormatIndicesBrackets:
138+
if key == "" {
139+
formattedKey = strconv.Itoa(i)
140+
} else {
141+
formattedKey = key + "[" + strconv.Itoa(i) + "]"
142+
}
143+
default:
144+
return fmt.Errorf("apiform: unsupported array format")
145+
}
146+
147+
if err := e.encodeValue(formattedKey, val.Index(i), writer); err != nil {
148+
return err
149+
}
150+
}
151+
return nil
152+
}
153+
154+
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
155+
156+
func escapeQuotes(s string) string {
157+
return quoteEscaper.Replace(s)
158+
}
159+
160+
func (e *encoder) encodeReader(key string, val reflect.Value, writer *multipart.Writer) error {
161+
reader, ok := val.Convert(reflect.TypeOf((*io.Reader)(nil)).Elem()).Interface().(io.Reader)
162+
if !ok {
163+
return nil
164+
}
165+
166+
// Set defaults
167+
filename := "anonymous_file"
168+
contentType := "application/octet-stream"
169+
170+
// Get filename if available
171+
if named, ok := reader.(interface{ Filename() string }); ok {
172+
filename = named.Filename()
173+
} else if named, ok := reader.(interface{ Name() string }); ok {
174+
filename = path.Base(named.Name())
175+
}
176+
177+
// Get content type if available
178+
if typed, ok := reader.(interface{ ContentType() string }); ok {
179+
contentType = typed.ContentType()
180+
}
181+
182+
h := make(textproto.MIMEHeader)
183+
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
184+
escapeQuotes(key), escapeQuotes(filename)))
185+
h.Set("Content-Type", contentType)
186+
187+
filewriter, err := writer.CreatePart(h)
188+
if err != nil {
189+
return err
190+
}
191+
_, err = io.Copy(filewriter, reader)
192+
return err
193+
}
194+
195+
func (e *encoder) encodeMap(key string, val reflect.Value, writer *multipart.Writer) error {
196+
type mapPair struct {
197+
key string
198+
value reflect.Value
199+
}
200+
201+
if key != "" {
202+
key = key + "."
203+
}
204+
205+
// Collect and sort map entries for deterministic output
206+
pairs := []mapPair{}
207+
iter := val.MapRange()
208+
for iter.Next() {
209+
if iter.Key().Type().Kind() != reflect.String {
210+
return fmt.Errorf("cannot encode a map with a non string key")
211+
}
212+
pairs = append(pairs, mapPair{key: iter.Key().String(), value: iter.Value()})
213+
}
214+
215+
sort.Slice(pairs, func(i, j int) bool {
216+
return pairs[i].key < pairs[j].key
217+
})
218+
219+
// Process sorted pairs
220+
for _, p := range pairs {
221+
if err := e.encodeValue(key+p.key, p.value, writer); err != nil {
222+
return err
223+
}
224+
}
225+
226+
return nil
227+
}

internal/apiform/form.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package apiform
2+
3+
type Marshaler interface {
4+
MarshalMultipart() ([]byte, string, error)
5+
}
6+
7+
type FormFormat int
8+
9+
const (
10+
// FormatRepeat represents arrays as repeated keys with the same value
11+
FormatRepeat FormFormat = iota
12+
// Comma-separated values 1,2,3
13+
FormatComma
14+
// FormatBrackets uses the key[] notation for arrays
15+
FormatBrackets
16+
// FormatIndicesDots uses key.0, key.1, etc. notation
17+
FormatIndicesDots
18+
// FormatIndicesBrackets uses key[0], key[1], etc. notation
19+
FormatIndicesBrackets
20+
)

0 commit comments

Comments
 (0)