Skip to content

Commit

Permalink
fix(flatten): remove unused acts recursively
Browse files Browse the repository at this point in the history
Whenever unused definitions are removed, some new definitions may appear
as unused. This PR goes does this rabbit hole to delete all unused
definitions until no unused candidate shows up.

* contributes go-swagger/go-swagger#2657

Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
  • Loading branch information
fredbi committed Dec 23, 2023
1 parent 6064bf5 commit 3f1a920
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 4 deletions.
19 changes: 19 additions & 0 deletions fixtures/bugs/2657/schema-flattened.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
consumes:
- application/json
produces:
- application/json
schemes:
- http
- https
swagger: "2.0"
info:
title: Sample API.
version: 1.0.0
paths:
/hello:
get:
description: Hello
operationId: hello
responses:
"200":
description: success
48 changes: 48 additions & 0 deletions fixtures/bugs/2657/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"schemes": [
"http",
"https"
],
"swagger": "2.0",
"info": {
"title": "Sample API.",
"version": "1.0.0"
},
"paths": {
"/hello": {
"get": {
"description": "Hello",
"operationId": "hello",
"responses": {
"200": {
"description": "success"
}
}
}
}
},
"definitions": {
"Author": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"Book": {
"type": "object",
"properties": {
"author": {
"$ref": "#/definitions/Author"
}
}
}
}
}
3 changes: 0 additions & 3 deletions fixtures/expected/external-references-2.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@
}
}
},
"named": {
"type": "string"
},
"record": {
"type": "object",
"properties": {
Expand Down
9 changes: 9 additions & 0 deletions flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ func nameInlinedSchemas(opts *FlattenOpts) error {
}

func removeUnused(opts *FlattenOpts) {
for removeUnusedSinglePass(opts) {
// continue until no unused definition remains
}
}

func removeUnusedSinglePass(opts *FlattenOpts) (hasRemoved bool) {
expected := make(map[string]struct{})
for k := range opts.Swagger().Definitions {
expected[path.Join(definitionsPath, jsonpointer.Escape(k))] = struct{}{}
Expand All @@ -277,6 +283,7 @@ func removeUnused(opts *FlattenOpts) {
}

for k := range expected {
hasRemoved = true
debugLog("removing unused definition %s", path.Base(k))
if opts.Verbose {
log.Printf("info: removing unused definition: %s", path.Base(k))
Expand All @@ -285,6 +292,8 @@ func removeUnused(opts *FlattenOpts) {
}

opts.Spec.reload() // re-analyze

return hasRemoved
}

func importKnownRef(entry sortref.RefRevIdx, refStr, newName string, opts *FlattenOpts) error {
Expand Down
19 changes: 18 additions & 1 deletion flatten_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func TestFlatten_ImportExternalReferences(t *testing.T) {
require.True(t, ref.HasFragmentOnly)
}

// now try complete flatten
// now try complete flatten, with unused definitions removed
sp = antest.LoadOrFail(t, bp)
an := New(sp)

Expand Down Expand Up @@ -1383,6 +1383,23 @@ func TestFlatten_1898(t *testing.T) {
require.Contains(t, def.Properties, "result")
}

func TestFlatten_RemoveUnused_2657(t *testing.T) {
log.SetOutput(io.Discard)
defer log.SetOutput(os.Stdout)

bp := filepath.Join("fixtures", "bugs", "2657", "schema.json")
sp := antest.LoadOrFail(t, bp)
an := New(sp)

require.NoError(t, Flatten(FlattenOpts{
Spec: an, BasePath: bp, Verbose: true,
Minimal: true,
Expand: false,
RemoveUnused: true,
}))
require.Empty(t, sp.Definitions)
}

func getDefinition(t testing.TB, sp *spec.Swagger, key string) string {
d, ok := sp.Definitions[key]
require.Truef(t, ok, "Expected definition for %s", key)
Expand Down

0 comments on commit 3f1a920

Please sign in to comment.