feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
package sdk
|
|
|
|
|
|
|
|
|
|
import (
|
2026-03-31 16:45:45 +00:00
|
|
|
"context"
|
|
|
|
|
|
2026-03-26 14:58:13 +00:00
|
|
|
"dappco.re/go/core"
|
2026-03-26 17:41:53 +00:00
|
|
|
"dappco.re/go/core/build/internal/ax"
|
2026-03-22 01:34:37 +00:00
|
|
|
coreerr "dappco.re/go/core/log"
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// commonSpecPaths are checked in order when no spec is configured.
|
|
|
|
|
var commonSpecPaths = []string{
|
|
|
|
|
"api/openapi.yaml",
|
2026-04-01 20:45:45 +00:00
|
|
|
"api/openapi.yml",
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
"api/openapi.json",
|
|
|
|
|
"openapi.yaml",
|
2026-04-01 20:45:45 +00:00
|
|
|
"openapi.yml",
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
"openapi.json",
|
|
|
|
|
"docs/api.yaml",
|
2026-04-01 20:45:45 +00:00
|
|
|
"docs/api.yml",
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
"docs/api.json",
|
|
|
|
|
"swagger.yaml",
|
2026-04-01 20:45:45 +00:00
|
|
|
"swagger.yml",
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
"swagger.json",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DetectSpec finds the OpenAPI spec file.
|
|
|
|
|
// Priority: config path -> common paths -> Laravel Scramble.
|
2026-03-31 18:33:36 +01:00
|
|
|
//
|
|
|
|
|
// path, err := s.DetectSpec() // → "api/openapi.yaml", nil
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
func (s *SDK) DetectSpec() (string, error) {
|
|
|
|
|
// 1. Check configured path
|
|
|
|
|
if s.config.Spec != "" {
|
2026-03-26 17:41:53 +00:00
|
|
|
specPath := ax.Join(s.projectDir, s.config.Spec)
|
2026-03-30 00:05:46 +00:00
|
|
|
if ax.IsFile(specPath) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
return specPath, nil
|
|
|
|
|
}
|
2026-03-16 21:03:21 +00:00
|
|
|
return "", coreerr.E("sdk.DetectSpec", "configured spec not found: "+s.config.Spec, nil)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. Check common paths
|
|
|
|
|
for _, p := range commonSpecPaths {
|
2026-03-26 17:41:53 +00:00
|
|
|
specPath := ax.Join(s.projectDir, p)
|
2026-03-30 00:05:46 +00:00
|
|
|
if ax.IsFile(specPath) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
return specPath, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3. Try Laravel Scramble detection
|
2026-03-31 16:45:45 +00:00
|
|
|
composerPath := ax.Join(s.projectDir, "composer.json")
|
|
|
|
|
if ax.IsFile(composerPath) {
|
|
|
|
|
data, err := ax.ReadFile(composerPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if containsScramble(string(data)) {
|
|
|
|
|
specPath, err := s.detectScramble()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
return specPath, nil
|
|
|
|
|
}
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-16 21:03:21 +00:00
|
|
|
return "", coreerr.E("sdk.DetectSpec", "no OpenAPI spec found (checked config, common paths, Scramble)", nil)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// detectScramble checks for Laravel Scramble and exports the spec.
|
|
|
|
|
func (s *SDK) detectScramble() (string, error) {
|
2026-03-26 17:41:53 +00:00
|
|
|
composerPath := ax.Join(s.projectDir, "composer.json")
|
2026-03-30 00:05:46 +00:00
|
|
|
if !ax.IsFile(composerPath) {
|
2026-03-16 21:03:21 +00:00
|
|
|
return "", coreerr.E("sdk.detectScramble", "no composer.json", nil)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for scramble in composer.json
|
2026-03-30 00:05:46 +00:00
|
|
|
data, err := ax.ReadFile(composerPath)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Simple check for scramble package
|
2026-03-30 01:03:04 +00:00
|
|
|
if !containsScramble(string(data)) {
|
2026-03-16 21:03:21 +00:00
|
|
|
return "", coreerr.E("sdk.detectScramble", "scramble not found in composer.json", nil)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-31 16:45:45 +00:00
|
|
|
scrambleSpecPath := ax.Join(s.projectDir, "api.json")
|
|
|
|
|
|
|
|
|
|
phpCommand, err := resolvePHPCli()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", coreerr.E("sdk.detectScramble", "php CLI not found", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := ax.ExecDir(context.Background(), s.projectDir, phpCommand, "artisan", "scramble:export", "--path=api.json"); err != nil {
|
|
|
|
|
return "", coreerr.E("sdk.detectScramble", "scramble export failed", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ax.IsFile(scrambleSpecPath) {
|
|
|
|
|
return "", coreerr.E("sdk.detectScramble", "scramble export did not create api.json", nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return scrambleSpecPath, nil
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// containsScramble checks if composer.json includes scramble.
|
|
|
|
|
func containsScramble(content string) bool {
|
2026-03-26 14:58:13 +00:00
|
|
|
return core.Contains(content, "dedoc/scramble") ||
|
|
|
|
|
core.Contains(content, "\"scramble\"")
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
}
|
2026-03-31 16:45:45 +00:00
|
|
|
|
|
|
|
|
func resolvePHPCli() (string, error) {
|
|
|
|
|
return ax.ResolveCommand("php",
|
|
|
|
|
"/usr/bin/php",
|
|
|
|
|
"/usr/local/bin/php",
|
|
|
|
|
"/opt/homebrew/bin/php",
|
|
|
|
|
)
|
|
|
|
|
}
|