-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #90 from Peefy/add-more-patch-and-loop-modules
feat: add more modules about merge and loop
- Loading branch information
Showing
15 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
## Introduction | ||
|
||
`json_merge_patch` is a module for applying JSON merge patches (RFC 7368) for KCL values. | ||
|
||
## How to Use | ||
|
||
+ Add the dependency | ||
|
||
```shell | ||
kcl mod add json_merge_patch | ||
``` | ||
|
||
+ Write the code | ||
|
||
```python | ||
import json_merge_patch as p | ||
|
||
data1 = { | ||
"firstName": "John", | ||
"lastName": "Doe", | ||
"age": 30, | ||
"address": { | ||
"streetAddress": "1234 Main St", | ||
"city": "New York", | ||
"state": "NY", | ||
"postalCode": "10001" | ||
}, | ||
"phoneNumbers": [ | ||
{ | ||
"type": "home", | ||
"number": "212-555-1234" | ||
}, | ||
{ | ||
"type": "work", | ||
"number": "646-555-5678" | ||
} | ||
] | ||
} | ||
data2 = { | ||
"firstName": "John", | ||
"lastName": "Doe", | ||
"age": 30, | ||
"address": { | ||
"streetAddress": "1234 Main St", | ||
"city": "New York", | ||
"state": "NY", | ||
"postalCode": None | ||
}, | ||
"phoneNumbers": [ | ||
{ | ||
"type": "work", | ||
"number": "646-555-5678" | ||
} | ||
] | ||
} | ||
data_merge = p.merge(data1, data2) | ||
``` | ||
|
||
## Resource | ||
|
||
The code source and documents are [here](https://github.com/kcl-lang/artifacthub/tree/main/json_merge_patch) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[package] | ||
name = "json_merge_patch" | ||
version = "0.1.0" | ||
description = "`json_merge_patch` is a module for applying JSON merge patches (RFC 7368) for KCL values." | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
KCL_BUILTIN_TYPES = ["int", "str", "bool", "float", "None", "UndefinedType", "any", "list", "dict", "function", "number_multiplier"] | ||
NULL_CONSTANTS = [Undefined, None] | ||
|
||
is_schema = lambda obj: any -> bool { | ||
typeof(obj) not in KCL_BUILTIN_TYPES | ||
|
||
} | ||
is_config = lambda obj: any -> bool { | ||
typeof(obj) == "dict" or is_schema(obj) | ||
} | ||
|
||
_looper_n = lambda elements: [any], n: int, func: (any, any) -> any, initial: any-> any { | ||
assert n >= 0 | ||
result = initial | ||
if n < len(elements): | ||
result = _looper_n(elements, n + 1, func, func(result, elements[n])) | ||
result | ||
} | ||
|
||
looper = lambda initial: any, elements: [any], func: (any, any) -> any -> any { | ||
_looper_n(elements, 0, func, initial) | ||
} | ||
|
||
for_each = lambda elements: [any], func: (any) -> any { | ||
_looper_n(elements, 0, lambda v, e { | ||
func(e) | ||
}, Undefined) | ||
} | ||
|
||
looper_enumerate = lambda initial: any, elements: [any] | {str:}, func: (any, str | int, any) -> any -> any { | ||
looper(initial, [{"k" = k, "v" = v} for k, v in elements], lambda initial, value { | ||
func(initial, value.k, value.v) | ||
}) | ||
} | ||
|
||
merge = lambda src: any, obj: any -> any { | ||
result = src | ||
if not is_config(src): | ||
result = {} | ||
if not is_config(obj): | ||
result = obj | ||
else: | ||
result = looper_enumerate(result, obj, lambda result, key, value { | ||
target = result[key] | ||
if is_config(value): | ||
if is_config(target): | ||
result |= {"{}".format(key) = merge(target, value)} | ||
else: | ||
result |= {"{}".format(key) = merge({}, value)} | ||
elif value in NULL_CONSTANTS: | ||
result |= {"{}".format(key) = Undefined} | ||
result = {k: v for k, v in result if k != key} | ||
else: | ||
result |= {"{}".format(key) = value} | ||
result | ||
}) | ||
result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
test_merge = lambda { | ||
cases: [[]] = [ | ||
[ | ||
{ | ||
"title": "Goodbye!" | ||
"author": { | ||
"givenName": "John" | ||
"familyName": "Doe" | ||
} | ||
"tags": ["example", "sample"] | ||
"content": "This will be unchanged" | ||
} | ||
{ | ||
"title": "Hello!" | ||
"phoneNumber": "+01-123-456-7890" | ||
"author": {"familyName": None} | ||
"tags": ["example"] | ||
} | ||
{ | ||
"title": "Hello!" | ||
"author": {"givenName": "John"} | ||
"tags": ["example"] | ||
"content": "This will be unchanged" | ||
"phoneNumber": "+01-123-456-7890" | ||
} | ||
] | ||
[{"a": "b"}, {"a": "c"}, {"a": "c"}] | ||
[{"a": "b"}, {"b": "c"}, {"a": "b", "b": "c"}] | ||
[{"a": "b"}, {"a": None}, {}] | ||
[{"a": "b", "b": "c"}, {"a": None}, {"b": "c"}] | ||
[{"a": ["b"]}, {"a": "c"}, {"a": "c"}] | ||
[{"a": "c"}, {"a": ["b"]}, {"a": ["b"]}] | ||
[ | ||
{ | ||
"a": {"b": "c"} | ||
} | ||
{ | ||
"a": {"b": "d", "c": None} | ||
} | ||
{ | ||
"a": {"b": "d"} | ||
} | ||
] | ||
[{"a": [{"b": "c"}]}, {"a": [1]}, {"a": [1]}] | ||
[["a", "b"], ["c", "d"], ["c", "d"]] | ||
[{"a": "foo"}, None, None] | ||
[{"a": "foo"}, "bar", "bar"] | ||
[{"e": None}, {"a": 1}, {"e": None, "a": 1}] | ||
[[1, 2], {"a": "b", "c": None}, {"a": "b"}] | ||
[ | ||
{} | ||
{ | ||
"a": { | ||
"bb": {"ccc": None} | ||
} | ||
} | ||
{ | ||
"a": { | ||
"bb": {} | ||
} | ||
} | ||
] | ||
] | ||
for_each(cases, lambda case { | ||
data1 = case[0] | ||
data2 = case[1] | ||
expected = case[2] | ||
got = merge(data1, data2) | ||
assert str(got) == str(expected), "expected ${expected}, got ${got}" | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
## Introduction | ||
|
||
`looper` is a KCL loop library | ||
|
||
## Resource | ||
|
||
The Code source and documents are [here](https://github.com/kcl-lang/modules/tree/main/looper) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[package] | ||
name = "looper" | ||
version = "0.0.1" | ||
description = "`looper` is a KCL loop library" | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
_looper_n = lambda elements: [any], n: int, func: (any, any) -> any, initial: any-> any { | ||
assert n >= 0 | ||
result = initial | ||
if n < len(elements): | ||
result = _looper_n(elements, n + 1, func, func(result, elements[n])) | ||
result | ||
} | ||
|
||
looper = lambda initial: any, elements: [any], func: (any, any) -> any -> any { | ||
_looper_n(elements, 0, func, initial) | ||
} | ||
|
||
for_each = lambda elements: [any], func: (any) -> any { | ||
[func(i) for i in elements] | ||
Undefined | ||
} | ||
|
||
looper_enumerate = lambda initial: any, elements: [any] | {str:}, func: (any, str | int, any) -> any -> any { | ||
looper(initial, [{"k" = k, "v" = v} for k, v in elements], lambda initial, value { | ||
func(initial, value.k, value.v) | ||
}) | ||
} | ||
|
||
for_each_looper_enumerate = lambda elements: [any] | {str:}, func: (str | int, any) -> any -> any { | ||
[func(k, v) for k, v in elements] | ||
Undefined | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
test_merge = lambda { | ||
cases: [[]] = [ | ||
[ | ||
0 | ||
[1, 2, 3] | ||
lambda v, i { | ||
v + i | ||
} | ||
6 | ||
] | ||
[ | ||
1 | ||
[1, 2, 3] | ||
lambda v, i { | ||
v * i | ||
} | ||
6 | ||
] | ||
] | ||
for_each(cases, lambda case { | ||
initial = case[0] | ||
values = case[1] | ||
func = case[2] | ||
expected = case[3] | ||
got = looper(initial, values, func) | ||
assert got == expected, "expected ${expected}, got ${got}" | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
## Introduction | ||
|
||
`update-image-tag` is a KCL mutation module to add istio sidecar inject labels for `Namespace` resources. | ||
|
||
## Resource | ||
|
||
The Code sources and documents are [here](https://github.com/kcl-lang/modules/tree/main/update-image-tag) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "update-image-tag" | ||
edition = "*" | ||
version = "0.1.0" | ||
description = "`update-image-tag` is a KCL mutation module" | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
schema Params: | ||
deployName: str | ||
containerName: str | ||
image: str | ||
|
||
params: Params = option("params") | ||
|
||
_looper_n = lambda elements: [any], n: int, func: (any, any) -> any, initial: any-> any { | ||
assert n >= 0 | ||
result = initial | ||
if n < len(elements): | ||
result = _looper_n(elements, n + 1, func, func(result, elements[n])) | ||
result | ||
} | ||
|
||
looper = lambda initial: any, elements: [any], func: (any, any) -> any -> any { | ||
_looper_n(elements, 0, func, initial) | ||
} | ||
|
||
strategy_merge_patches_with_name = lambda containers: [{str:}], patches: [{str:}] -> [{str:}] { | ||
looper(containers, patches, lambda containers: [{str:}], patch: {str:} { | ||
patch_index_list = [i for i, c in containers if patch.name and c.name == patch.name] | ||
if patch_index_list: | ||
patched_containers = containers | [patch if patch.name and c.name == patch.name else {} for i, c in containers if patch.name and c.name == patch.name] | ||
else: | ||
patched_containers = containers + [patch] | ||
patched_containers | ||
|
||
}) | ||
|
||
} | ||
items = [item | { | ||
if item.kind == "Deployment" and params?.deployName and params?.containerName and item.metadata.name == params?.deployName: | ||
spec.template.spec.containers = strategy_merge_patches_with_name(item.spec.template.spec.containers, [{ | ||
name = params?.containerName | ||
image = params?.image | ||
}]) | ||
|
||
} for item in option("items") or []] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
test_strategy_merge_patches_with_name = lambda { | ||
containers = [ | ||
{ | ||
name = "foo" | ||
image = "foo:1.10" | ||
} | ||
{ | ||
name = "bar" | ||
image = "bar:1.20" | ||
} | ||
] | ||
assert strategy_merge_patches_with_name(containers, [{ | ||
name = "foo" | ||
image = "foofoo" | ||
}])[0].image == "foofoo" | ||
assert strategy_merge_patches_with_name(containers, [{ | ||
name = "foobar" | ||
image = "foofoo" | ||
}])[2].image == "foofoo" | ||
} |