Skip to content

Commit

Permalink
with deref, not expanded as possible
Browse files Browse the repository at this point in the history
  • Loading branch information
podhmo committed Nov 26, 2016
1 parent 5a85fce commit 0945f07
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 36 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,7 @@ example5:
cat .tmp/03* | gsed 's/^/ /g' >> example5.rst
rm -r .tmp

.PHONY: example
examples: example example2 example3 example4 example5

.PHONY: examples
.PHONY: watch updatespec test regenerate
38 changes: 25 additions & 13 deletions example5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ deref/group/group.yaml
- A
- B
- C
color:
$ref: "../color/rgb.yaml#/definitions/color"
deref/main.yaml
Expand All @@ -93,42 +91,56 @@ deref/main.yaml
- x.yaml as X
definitions:
foo:
$ref: "./group/group.yaml#/definitions/group"
color:
$ref: "group/group.yaml#/definitions/color"
$ref: "color/cmyk.yaml#/definitions/color"
rgb:
$ref: "color/rgb.yaml#/definitions/color"
cmyk:
$ref: "color/cmyk.yaml#/definitions/color"
deref/x.yaml

.. code-block:: yaml
x-bundler-compose:
- group/group.yaml
definitions:
color:
$ref: color/cmyk.yaml#/definitions/color
$ref: "color/rgb.yaml#/definitions/color"
## generated.yaml

.. code-block:: yaml
definitions:
XGroup:
type: string
enum:
- A
- B
- C
XColor:
type: string
enum:
- r
- g
- b
color:
type: string
enum:
- C
- M
- Y
- K
foo:
type: string
enum:
- A
- B
- C
color:
rgb:
x-conflicted: color/rgb.yaml#/definitions/color
type: string
enum:
- r
- g
- b
cmyk:
$ref: '#/definitions/color'
2 changes: 0 additions & 2 deletions examples/deref/group/group.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@ definitions:
- A
- B
- C
color:
$ref: "../color/rgb.yaml#/definitions/color"
8 changes: 5 additions & 3 deletions examples/deref/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ x-bundler-compose:
- x.yaml as X

definitions:
foo:
$ref: "./group/group.yaml#/definitions/group"
color:
$ref: "group/group.yaml#/definitions/color"
$ref: "color/cmyk.yaml#/definitions/color"
rgb:
$ref: "color/rgb.yaml#/definitions/color"
cmyk:
$ref: "color/cmyk.yaml#/definitions/color"
5 changes: 4 additions & 1 deletion examples/deref/x.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
x-bundler-compose:
- group/group.yaml

definitions:
color:
$ref: color/cmyk.yaml#/definitions/color
$ref: "color/rgb.yaml#/definitions/color"
2 changes: 1 addition & 1 deletion examples/swagger-bundler.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ exposed = x-bundler-exposed
# or
# a/b/c/d.py:function_name
compose =
bundle =
bundle = swagger_bundler.postscript:deref_support_for_extra_file
add_namespace =
validate =
5 changes: 4 additions & 1 deletion swagger_bundler/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ def options(self):
def identifier(self):
return self.resolver.identifier

@property
def ns(self):
return self.resolver.ns

def _on_load_failure(self, src, e=None):
if e is not None:
sys.stderr.write("{}: {}\n".format(type(e), e))
Expand Down Expand Up @@ -229,7 +233,6 @@ def make_subcontext(self, src, data=None):
exposed_list = subcontext.detector.detect_exposed()
new_compose_target_list = [c for c in subcontext.detector.detect_compose() if c in exposed_list]
subcontext.detector.update_compose(new_compose_target_list)

return subcontext

def make_subcontext_from_port(self, port):
Expand Down
18 changes: 17 additions & 1 deletion swagger_bundler/langhelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,20 @@ def titleize(s):
if not s:
return s
else:
return "{}{}".format(s[0].title(), s[1:])
return "{}{}".format(s[0].upper(), s[1:])


def untitlize(s):
"""FooBar -> fooBar"""
if not s:
return s
else:
return "{}{}".format(s[0].lower(), s[1:])


def guess_name(s, ns):
yield s
if ns:
unprefixed = s[len(ns):]
yield unprefixed
yield untitlize(unprefixed)
52 changes: 39 additions & 13 deletions swagger_bundler/postscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import copy
from collections import deque
from collections import OrderedDict
from .langhelpers import titleize
from .langhelpers import titleize, guess_name
from . import highlight


Expand All @@ -22,7 +22,7 @@ def echo(ctx, data, *args, **kwargs):
_rx_cache = {}


def deref_support_for_extra_file(ctx, data, *args, targets=tuple(["definitions", "paths", "responses"]), **kwargs):
def deref_support_for_extra_file(ctx, rootdata, *args, targets=tuple(["definitions", "paths", "responses"]), **kwargs):
cache_k = tuple(targets)
if cache_k not in _rx_cache:
_rx_cache[cache_k] = re.compile("#/({})/".format("|".join(targets)))
Expand All @@ -33,39 +33,65 @@ def deref_support_for_extra_file(ctx, data, *args, targets=tuple(["definitions",
# path :: (<name>/)*<name>
# section :: 'definitions' | 'paths' | 'responses'

def deref(d, ctx, i):
def deref(d, ctx, paths):
if "$ref" not in d:
return d, i
return d, paths
try:
m = separator_rx.search(d["$ref"])
if m is None:
highlight.show_on_warning("invalid ref: {}\n".format(d["$ref"]))
return d, i
return d, paths

# plain ref
if m.start() == 0:
return d, i
return d, paths

# with extra path
path = d["$ref"][:m.start()]
section = m.group(1)
name = d["$ref"][m.end():]
subctx = ctx.make_subcontext(path)
return deref(subctx.data[section][name], ctx=subctx, i=i + 1)

# gueesing key (this is heuristic)
section_store = subctx.data[section]
for guessed in guess_name(name, subctx.ns):
if guessed in section_store:
paths.append((section, name))
return deref(section_store[guessed], ctx=subctx, paths=paths)
highlight.show_on_warning("not found ref: {}\n".format(d["$ref"]))
return d, paths
except (IndexError, ValueError) as e:
highlight.show_on_warning(str(e))

def on_ref_found(d):
data, i = deref(d, ctx, 0)
if i > 0:
d.pop("$ref")
d.update(data)
data, paths = deref(d, ctx, [])
if paths:
original_ref = d.pop("$ref")
section, name = paths[-1]

d["$ref"] = "#/{}/{}".format(section, name)
if section not in rootdata:
rootdata[section] = OrderedDict()

if name not in rootdata[section]:
rootdata[section][name] = data
elif d == rootdata[section][name]:
d.pop("$ref")
d.update(data)
else:
refpath = "#/{}/{}".format(section, name)
if rootdata[section][name] != data:
d["x-conflicted"] = original_ref
msg = "{} is conflicted. (where file={!r} ref={!r})".format(refpath, ctx.path, original_ref)
highlight.show_on_warning(msg)
d.pop("$ref")
d.update(data)

w = LooseDictWalker(on_container=on_ref_found)
q = ["$ref"]
for section in targets:
if section in data:
w.walk(q, data[section])
if section in rootdata:
w.walk(q, rootdata[section])


def add_responses_default(ctx, data, *args, **kwargs):
Expand Down

0 comments on commit 0945f07

Please sign in to comment.