Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve Contains_key Closes #305 #603

Merged
merged 16 commits into from
Mar 27, 2024
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

### Checklist
- [ ] Pull request details were added to CHANGELOG.md
- [ ] Valid examples WDL's were added or updated to the SPEC.md (see the [guide](https://github.com/openwdl/wdl-tests/blob/main/docs/MarkdownTests.md) on writing markdown tests)
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ version development
consist of multiple files.
[PR 241](https://github.com/openwdl/wdl/pull/241) by @cjllanwarne.

+ Added `contains_key` function to standard library.


version 1.1.1
---------------------------

Expand Down
2 changes: 1 addition & 1 deletion RFC.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ RFC Process

Most technical decisions are decided through the "RFC" ([Request for Comments](https://en.wikipedia.org/wiki/Request_for_Comments)) process. Small changes, such as minor grammatical edits to the specification, do not need to need to follow the RFC process. However, if one intends to make a substantive change to the WDL specification , the following process should be adhered to:

1. Ideally have an informal discussion of the topic on the [mailing list](https://groups.google.com/forum/#!forum/openwdl) and/or the [gitter channel](https://gitter.im/openwdl/wdl) in order to gauge basic viability. As a rule of thumb, receiving encouraging feedback from long-standing community members is a good indication that the RFC is worth pursuing.
1. Ideally have an informal discussion of the topic on [Slack](https://join.slack.com/t/openwdl/shared_invite/zt-ctmj4mhf-cFBNxIiZYs6SY9HgM9UAVw) and/or [GitHub discussions](https://github.com/openwdl/wdl/discussions) in order to gauge basic viability. As a rule of thumb, receiving encouraging feedback from long-standing community members is a good indication that the RFC is worth pursuing.
2. Write up a formal proposal, including requested changes to the current specification, as a pull request on GitHub
3. A core team member will be assigned as the *shepherd* of this RFC. The shepherd shall be responsible for keeping the discussion moving and ensuring all concerns are responded to.
4. Work to build broad support from the community. Encouraging people to comment, show support, show dissent, etc. Ultimately the level of community support for a change will decide its fate.
Expand Down
160 changes: 160 additions & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ Revisions to this specification are made periodically in order to correct errors
- [`as_pairs`](#as_pairs)
- [`as_map`](#as_map)
- [`keys`](#keys)
- [✨ `contains_key`](#-contains_key)
- [`collect_by_key`](#collect_by_key)
- [Other Functions](#other-functions)
- [`defined`](#defined)
Expand Down Expand Up @@ -9209,6 +9210,165 @@ Example output:
</p>
</details>

### ✨ `contains_key`

```
Map[P, Y], P), Boolean contains_key(Map[P?, Y], P?)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

```

Given a key-value type collection (`Map`, `Struct`, or `Object`) and a key, tests whether the collection contains an entry with the given key.

**Parameters**

1. `Map[P, Y]`|`Struct`|`Object`: Collection to search for the key.
2. `P|Array[String]`: The key to search. If the first argument is a `Map`, then the key must be of the same type as the `Map`'s key type. If the `Map`'s key type is optional then the key may also be optional. If the first argument is a `Map[String, Y]`, `Struct`, or `Object`, then the key may be either a `String` or `Array[String]`.

**Returns**: `true` if the collection contains the key, otherwise false.

**Example**

<details>
<summary>
Example: get_values.wdl

```wdl
version 1.2

struct Person {
String name
Map[String, String]? details
}

workflow get_ints_and_exts {
input {
Map[String, Int] m
String key1
String key2
Person p1
Person p2
}

output {
Int? i1 = m[s1] if contains_key(m, key1) else None
Int? i2 = m[s2] if contains_key(m, key2) else None
String? phone1 = p1.details["phone"] if contains_key(p1, ["details", "phone"]) else None
String? phone2 = p2.details["phone"] if contains_key(p2, ["details", "phone"]) else None
}
}
```
</summary>
<p>
Example input:

```json
{
"get_values.m": {"a": 1, "b": 2},
"get_values.key1": "a",
"get_values.key2": "c",
"get_values.p1": {
"name": "John",
"details": {
"phone": "123-456-7890"
}
},
"get_values.p2": {
"name": "Agent X"
}
}
```

Example output:

```json
{
"get_ints_and_exts.i1": 1,
"get_ints_and_exts.i2": null,
"get_ints_and_exts.phone1": "123-456-7890",
"get_ints_and_exts.phone2": null,
}
```
</p>
</details>


```
Map[P, Y], P), Boolean contains_key(Map[P?, Y], P?)
```

Given a key-value type collection (`Map`, `Struct`, or `Object`) and a key, tests whether the collection contains an entry with the given key.

**Parameters**

1. `Map[P, Y]`|`Struct`|`Object`: Collection to search for the key.
2. `P|Array[String]`: The key to search. If the first argument is a `Map`, then the key must be of the same type as the `Map`'s key type. If the `Map`'s key type is optional then the key may also be optional. If the first argument is a `Map[String, Y]`, `Struct`, or `Object`, then the key may be either a `String` or `Array[String]`.

**Returns**: `true` if the collection contains the key, otherwise false.

**Example**

<details>
<summary>
Example: get_values.wdl

```wdl
version 1.2

struct Person {
String name
Map[String, String]? details
}

workflow get_ints_and_exts {
input {
Map[String, Int] m
String key1
String key2
Person p1
Person p2
}

output {
Int? i1 = m[s1] if contains_key(m, key1) else None
Int? i2 = m[s2] if contains_key(m, key2) else None
String? phone1 = p1.details["phone"] if contains_key(p1, ["details", "phone"]) else None
String? phone2 = p2.details["phone"] if contains_key(p2, ["details", "phone"]) else None
}
}
```
</summary>
<p>
Example input:

```json
{
"get_values.m": {"a": 1, "b": 2},
"get_values.key1": "a",
"get_values.key2": "c",
"get_values.p1": {
"name": "John",
"details": {
"phone": "123-456-7890"
}
},
"get_values.p2": {
"name": "Agent X"
}
}
```

Example output:

```json
{
"get_ints_and_exts.i1": 1,
"get_ints_and_exts.i2": null,
"get_ints_and_exts.phone1": "123-456-7890",
"get_ints_and_exts.phone2": null,
}
```
</p>
</details>

### `collect_by_key`

```
Expand Down
4 changes: 2 additions & 2 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Beginning with version 1.1.1, most of the examples in the WDL specification represent test cases.
All of these tests conform to the [WDL Markdown Test Specification](https://github.com/openwdl/wdl-tests/docs/MarkdownTests.md).
The tests extracted from the WDL specs can be found in the [wdl-tests](https://github.com/openwdl/wdl-tests/spec/) repository.
This folder contains the [test input files](data/) that are referenced by the test cases in the spec.
The tests extracted from the WDL specs can be found in the [wdl-tests](https://github.com/openwdl/wdl-tests/) repository.
This folder contains the [test input files](data/) that are referenced by the test cases in the spec.