Skip to content

Commit c49067e

Browse files
committed
feat: codegen
Introduce codegen tool like we have in other SDKs to ensure we can keep the SDK up-to-date with latest changes in our APIs and cover all of the APIs availabel to developers. The setup is just the same as for sumup-py or sumup-go. For now, we are keeping the implementation as similar to the previous version. Once there are breaking changes we might bump the SDK to v2.
1 parent 0133559 commit c49067e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+26040
-564
lines changed

.envrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export SUMUP_API_KEY="sup_sk_xlfTfAqFclXWxsx0LLTdS7UP927zXdV8q"
2+
export SUMUP_MERCHANT_CODE="MCZHMYCM"

.github/dependabot.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ updates:
44
directory: "/"
55
schedule:
66
interval: "weekly"
7-
open-pull-requests-limit: 3
7+
open-pull-requests-limit: 5
88
- package-ecosystem: "composer"
99
directory: "/"
1010
schedule:
1111
interval: "weekly"
12-
open-pull-requests-limit: 3
12+
open-pull-requests-limit: 5
13+
- package-ecosystem: "gomod"
14+
directory: "/codegen"
15+
schedule:
16+
interval: "weekly"
17+
open-pull-requests-limit: 5

.github/workflows/codegen.yaml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Codegen CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
paths:
8+
- "codegen/**"
9+
- ".github/workflows/codegen.yaml"
10+
pull_request:
11+
branches:
12+
- master
13+
paths:
14+
- "codegen/**"
15+
- ".github/workflows/codegen.yaml"
16+
17+
permissions:
18+
contents: read
19+
20+
defaults:
21+
run:
22+
working-directory: ./codegen
23+
24+
env:
25+
GOLANGCI_LINT_VERSION: v2.1.5
26+
27+
jobs:
28+
lint:
29+
name: Lint
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
33+
34+
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
35+
with:
36+
go-version-file: './codegen/go.mod'
37+
38+
- name: golangci-lint
39+
uses: golangci/golangci-lint-action@e7fa5ac41e1cf5b7d48e45e42232ce7ada589601 # v9.1.0
40+
with:
41+
version: ${{ env.GOLANGCI_LINT_VERSION }}
42+
working-directory: ./codegen
43+
44+
test:
45+
name: Test
46+
runs-on: ubuntu-latest
47+
steps:
48+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
49+
50+
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
51+
with:
52+
go-version-file: './codegen/go.mod'
53+
54+
- name: Run tests
55+
run: go test ./...

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ fmtcheck: vendor ## Check code formatting
2121
.PHONY: test
2222
test: vendor ## Run PHPUnit test suite
2323
composer test
24+
25+
.PHONY: generate
26+
generate: ## Generate SDK from the local OpenAPI specs
27+
cd codegen && go run ./... generate ../openapi.yaml ../src

codegen/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<div align="center">
2+
3+
# sumup-php codegen
4+
5+
A tiny OpenAPI specs to SDK generator for [sumup-ecom-php-sdk](https://github.com/sumup/sumup-ecom-php-sdk).
6+
7+
</div>
8+
9+
## Quickstart
10+
11+
Generate the SDK using:
12+
13+
```sh
14+
go run ./... generate ./openapi.yaml ./build
15+
```

codegen/generate.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/pb33f/libopenapi"
8+
"github.com/urfave/cli/v2"
9+
10+
"github.com/sumup/sumup-ecom-php-sdk/codegen/pkg/generator"
11+
)
12+
13+
func Generate() *cli.Command {
14+
var (
15+
out string
16+
)
17+
18+
return &cli.Command{
19+
Name: "generate",
20+
Usage: "Generate the PHP SDK",
21+
Args: true,
22+
Action: func(c *cli.Context) error {
23+
if !c.Args().Present() {
24+
return fmt.Errorf("empty argument, path to openapi specs expected")
25+
}
26+
27+
specPath := c.Args().First()
28+
29+
if err := os.MkdirAll(out, os.ModePerm); err != nil {
30+
return fmt.Errorf("create output directory %q: %w", out, err)
31+
}
32+
33+
spec, err := os.ReadFile(specPath)
34+
if err != nil {
35+
return fmt.Errorf("read specs: %w", err)
36+
}
37+
38+
doc, err := libopenapi.NewDocument(spec)
39+
if err != nil {
40+
return fmt.Errorf("load openapi document: %w", err)
41+
}
42+
43+
model, err := doc.BuildV3Model()
44+
if err != nil {
45+
return fmt.Errorf("build openapi v3 model: %w", err)
46+
}
47+
48+
g := generator.New(generator.Config{
49+
Out: out,
50+
})
51+
52+
if err := g.Load(&model.Model); err != nil {
53+
return fmt.Errorf("load specs: %w", err)
54+
}
55+
56+
if err := g.Build(); err != nil {
57+
return fmt.Errorf("build sdk: %w", err)
58+
}
59+
60+
return nil
61+
},
62+
Flags: []cli.Flag{
63+
&cli.StringFlag{
64+
Name: "out",
65+
Aliases: []string{"o"},
66+
Usage: "path of the output directory",
67+
Required: false,
68+
Destination: &out,
69+
Value: "../src/",
70+
},
71+
},
72+
}
73+
}

codegen/go.mod

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module github.com/sumup/sumup-ecom-php-sdk/codegen
2+
3+
go 1.24.7
4+
5+
require (
6+
github.com/lmittmann/tint v1.1.2
7+
github.com/pb33f/libopenapi v0.28.1
8+
github.com/urfave/cli/v2 v2.27.7
9+
)
10+
11+
require (
12+
github.com/bahlo/generic-list-go v0.2.0 // indirect
13+
github.com/buger/jsonparser v1.1.1 // indirect
14+
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
15+
github.com/iancoleman/strcase v0.3.0 // indirect
16+
github.com/pb33f/jsonpath v0.1.2 // indirect
17+
github.com/pb33f/ordered-map/v2 v2.3.0 // indirect
18+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
19+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
20+
go.yaml.in/yaml/v4 v4.0.0-rc.2 // indirect
21+
)

codegen/go.sum

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
2+
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
3+
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
4+
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
5+
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
6+
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
10+
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
11+
github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=
12+
github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
13+
github.com/pb33f/jsonpath v0.1.2 h1:PlqXjEyecMqoYJupLxYeClCGWEpAFnh4pmzgspbXDPI=
14+
github.com/pb33f/jsonpath v0.1.2/go.mod h1:TtKnUnfqZm48q7a56DxB3WtL3ipkVtukMKGKxaR/uXU=
15+
github.com/pb33f/libopenapi v0.28.1 h1:vqE1Q08F6ohABsyKcK8kX7HYkR/+sILXGwCgFzF+aOg=
16+
github.com/pb33f/libopenapi v0.28.1/go.mod h1:mHMHA3ZKSZDTInNAuUtqkHlKLIjPm2HN1vgsGR57afc=
17+
github.com/pb33f/ordered-map/v2 v2.3.0 h1:k2OhVEQkhTCQMhAicQ3Z6iInzoZNQ7L9MVomwKBZ5WQ=
18+
github.com/pb33f/ordered-map/v2 v2.3.0/go.mod h1:oe5ue+6ZNhy7QN9cPZvPA23Hx0vMHnNVeMg4fGdCANw=
19+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
20+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
21+
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
22+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
23+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
24+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
25+
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
26+
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
27+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
28+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
29+
go.yaml.in/yaml/v4 v4.0.0-rc.2 h1:/FrI8D64VSr4HtGIlUtlFMGsm7H7pWTbj6vOLVZcA6s=
30+
go.yaml.in/yaml/v4 v4.0.0-rc.2/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
31+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
32+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

codegen/main.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log/slog"
6+
"os"
7+
8+
"github.com/lmittmann/tint"
9+
"github.com/urfave/cli/v2"
10+
)
11+
12+
func main() {
13+
if err := App().Run(os.Args); err != nil {
14+
fmt.Fprintf(os.Stderr, "program exited: %v", err)
15+
os.Exit(1)
16+
}
17+
}
18+
19+
func App() *cli.App {
20+
return &cli.App{
21+
Name: "codegen",
22+
Usage: "sumup-php generator.",
23+
DefaultCommand: "generate",
24+
Before: func(ctx *cli.Context) error {
25+
logger := slog.New(tint.NewHandler(os.Stderr, nil))
26+
slog.SetDefault(logger)
27+
return nil
28+
},
29+
Commands: []*cli.Command{
30+
Generate(),
31+
},
32+
}
33+
}

codegen/pkg/extension/extension.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package extension
2+
3+
import (
4+
"github.com/pb33f/libopenapi/orderedmap"
5+
"go.yaml.in/yaml/v4"
6+
)
7+
8+
// Get extracts extension attributes from extensions.
9+
func Get[T any](ext *orderedmap.Map[string, *yaml.Node], key string) (T, bool) {
10+
var empty T
11+
if ext == nil {
12+
return empty, false
13+
}
14+
15+
if raw, ok := ext.Get(key); ok {
16+
var v T
17+
if err := raw.Decode(&v); err != nil {
18+
return empty, false
19+
}
20+
21+
return v, true
22+
}
23+
24+
return empty, false
25+
}
26+
27+
// GetOrDefault extracts extension attributes from extensions, returning def as default.
28+
func GetOrDefault[T any](ext *orderedmap.Map[string, *yaml.Node], key string, def T) T {
29+
if val, ok := Get[T](ext, key); ok {
30+
return val
31+
}
32+
33+
return def
34+
}

0 commit comments

Comments
 (0)